AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 237 |
r3wp | 1294 |
total: | 1531 |
results window for this page: [start: 1201 end: 1300]
world-name: r3wp
Group: Ann-Reply ... Reply to Announce group [web-public] | ||
Maxim: 28-Oct-2010 | Adrian you are having a very strange problem. the actual OS and opengl code being called is textbox 1.1 OpenGL I will try to look into it, though with the little I've seen the 5xxx series ATI cards do come up often has being "troublemakers" in OpenGL dev, though by all accounts the 10.10 drivers seem to cure problems for most users. now I'm not downplaying that its something in my code, its possible there is a little something to add explicitely to make your card work which is done implicitely on other setups... if you don't mind I'll use you to test anything I can find. you are at the opposite end of my setup, mobile nvidia card running on 32 bit xp. | |
Group: !AltME ... Discussion about AltME [web-public] | ||
Reichart: 24-Sep-2010 | Also, technically, a given send box should be directly connected to the given group, so you can send, and even if it is in transit or waiting you can go on and work on other messages. We do tag messages this way in Qtask, but we have seen this same bug, but don't have proof (as I do in AltME) that it is the program and not the operator. But I'm always on the look out for it since it can be a very dangerous bug for some people. This whole class of issue falls to a perceived form of latency, and a series of features are needed to suppress it. For example, instead of graying the out going message area, just make it look like it was sent, but also instantly add a “message hour glass” in the “New message” bar when on that group, and, also create a new tinted empty box in the thread saying something like “Waiting for new message to post”. This frees you up to go elsewhere. If you come back to the same group it is clear what state it is in. If you want to retrieve the sent message just click on the “Message hour glass” and it will bring it back into the input box. Lastly, of course, if you try to leave AltME before it is done sending, need to offer people a dialog warning them , and giving them access to the messages waiting. There is more, but yeah, it takes a lot to make this work. | |
Group: !REBOL3 ... [web-public] | ||
Andreas: 26-Oct-2010 | It returns the first series at the point of divergence. | |
BrianH: 18-Nov-2010 | Kaj, map! is object-like, hash is series-like. | |
Andreas: 29-Nov-2010 | Sunanda: RANDOM of a series in R3 modifies the series and returns a reference to the modified series. | |
Andreas: 29-Nov-2010 | So you append the same series 200 times to blk, and also shuffle this series 200 times. | |
Andreas: 29-Nov-2010 | And yes, that is an incompatible change in R3 over R2. RANDOM in R2 was not modifying a series argument. | |
BrianH: 29-Nov-2010 | I understand that there are limits to how efficient you can make copies. Making a copy is itself an inefficiency, since efficiency isn't just a CPU thing, memory usage matters too. However, this might not work as well when we are making a lot of series non-modifiable not just for protection, but in theory to make them sharable without conflicts. I'll put my concerns in the ticket. | |
Ladislav: 5-Jan-2011 | REBOL strings as well as REBOL blocks (parens, paths, the majority of series,...) use consecutive space | |
Ladislav: 11-Jan-2011 | While I see the WORDS-OF naming convention as coming from the C language, I am not a C hater to the extent to refuse it. As some noticed, it may even make the source code more human readable as in: length-of series versus length? series | |
Ladislav: 11-Jan-2011 | It is funny, that it looks, that people prefer length-of series to the form get-length series which is starting with a verb... | |
BrianH: 11-Jan-2011 | Some *? functions that might be better off as *-OF: ENCODING?, FILE-TYPE?, INDEX?, LENGTH?, SIGN? and SIZE?. Except for the first two the old names would need to stick around because of the legacy naming rules. Strangely enough, UTF? is OK because it is short for "UTF what?". The series contents functions have an implicit -OF :) | |
BrianH: 11-Jan-2011 | I'd be willing to let the series actions that return contents to continue to have the -OF be implicit, especially since they are legacy :) | |
Ladislav: 12-Jan-2011 | this naming convention doesn't work with MAXIMUM-OF and MINIMUM-OF, which don't actually return the maximum or minimum of a series, they return the series at the position of the maximum or minimum. Gregg has suggested that these be renamed to FIND-MAX and FIND-MIN instead, and this will probably happen (rarely used, really badly named). - I have got absolutely no problem with MAXIMUM-OF or MINIMUM-OF, FIND-MAX and FIND-MIN aren't any better, because they express the same, just in a less fortunate way (find is less descriptive than maximum/minimum) | |
Ladislav: 12-Jan-2011 | I do not think, that the name of a function should describe everything, so, if I really want to get the maximal of the values in a series, I can be content to know that the MAXIMUM-OF function exists and be prepared to read the doc string what it actually does. | |
BrianH: 12-Jan-2011 | And it wouldn't be INDEX-OF-MAXIMUM?: First of all, the ? is inappropriate, secondly, it returns the series, not the index. FIND-MAX isn't less descriptive because it references the behavior of MAX (which we have already learned means maximum) and FIND (which we know returns the argument series at the position of the thing found). We don't only get our conceptual context from English, we also get it from the rest of REBOL. | |
Oldes: 13-Jan-2011 | good... as an extension I have: const short int val = RXA_INT32(frm, 1); REBSER *ser = RL_MAKE_STRING(1, FALSE); RL_SET_CHAR(ser, 0, val ); RL_SET_CHAR(ser, 1, val >> 8); RXA_SERIES(frm, 1) = ser; RXA_TYPE(frm, 1) = RXT_BINARY; return RXR_VALUE; >> tm 100000 [to-ui16 300] == 0:00:00.016 | |
BrianH: 20-Jan-2011 | As an example of the CS tricks that immutability gives us, protecting a series should make it safe to share between R3 tasks without needing to copy it or synchronize access. That's nice :) | |
Gabriele: 5-Feb-2011 | find-nth: func [series value n] [ loop n [unless series: find series value [return none]] series ] | |
Kaj: 17-Feb-2011 | Is there any place in your extension where you create more than one series in one command? | |
Kaj: 17-Feb-2011 | Is there any place in your extension where series are passed between commands and are supposed to survive between calls? | |
BrianH: 1-Mar-2011 | There are a few functions in R3 that take the form of a CASE/all followed by a CASE. SAVE is one such function, though it has a series of IF statements at its beginning leftover from before that could be made more efficient by adding to the beginning of the CASE/all. | |
BrianH: 1-Mar-2011 | CASE/all is no more difficult to test than the series of IF statements it replaces. Easier to analyze, because it's more structured. | |
Ladislav: 1-Mar-2011 | CASE/all is no more difficult to test than the series of IF statements it replaces. - yes, sure that is true | |
Andreas: 24-Mar-2011 | >> m: map [a: 42] >> protect m >> m/a ** Script error: protected value or series - cannot modify Known bug? Not a bug, but a feature? | |
MikeL: 8-Apr-2011 | Thanks. Doc and I have had a series of discussions on it where he has helped me out. In particular was Cheyenne being able to pull IIS information authenticated to a Windows domain for presentation from Cheyenne. We got to ... some more detailed / dedicated Doc work needed because NTLM is tricky. That's not an option now because Red is a priority for everyone including me. But if Curl enables it ... | |
BrianH: 4-May-2011 | I would love it if we as a community were to really think through the (UN)PROTECT model, because the current model is incomplete (even for the stuff that works) and the proposed model is starting to look a bit awkward to use. Keep in mind that PROTECT may also be used to make series sharable among tasks, but that this isn't implemented and there is likely a better way to do this. I would love it if there was a good security model that can integrate well with REBOL semantics. | |
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.) | |
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 | 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 | 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 | 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. | |
BrianH: 13-May-2011 | On the other hand, I really don't know how to interpretet the results of R2's STATS function, so I'm taking your word for it that the series are created by the ++ calls. Which numbers tell you this? | |
Geomol: 13-May-2011 | Got it. Series are 32 bit pointer and 32 bit offset. So no additional space is wasted by having ++ return as it does. | |
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 | Brian, do ? stats in R2. I read it, as the /series refinement show BLOCKS as the second number. | |
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. | |
Geomol: 13-May-2011 | Makes sense. So the additional mem for the series ref. is on the stack (or whatever data structure is used), and if that area is reused between additional computations, no mem is wasted by ++. Correct? | |
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. | |
Geomol: 13-May-2011 | Yes, stats/series eat 3 blocks each time, it's called. | |
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 | 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. | |
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. | |
Kaj: 21-May-2011 | John, to keep your mind on the edge of the cliff, did you know about the global series table? :-) | |
Kaj: 21-May-2011 | Quite similar to the global symbols table, the existence of a global series table can be deduced, from the R3 extensions interface | |
Kaj: 21-May-2011 | A series value does not include an index. Only a reference does. So that's one indirection, from a value slot (with an index) to a series value | |
Kaj: 21-May-2011 | But there must be another indirection, from the series value to the actual storage location of its item slots, because the item storage can't be counted on to stay at the same memory address over garbage collection and callbacks or multitasking, but it must be deduced that the series value can be counted on to stay at the same memory address | |
Kaj: 21-May-2011 | So there must be a table of series descriptors apart from the actual series content | |
BrianH: 21-May-2011 | It wouldn't need to be a global table, it could be a heap space dedicated to series descriptors (a typed array in memory). Same purpose, more likely implementation. Precise collectors are often implemented with type-specific heap spaces, since it reduces fragmentation when you don't have a copying or compacting collector - REBOL's collector doesn't move values, supposedly. REBOL could get away with heap spaces for block data, string/binary data, and descriptors (maybe both object and series in the same heap space); there might be more, but adding more can make the memory management more complicated. | |
BrianH: 21-May-2011 | can't be counted on to stay at the same memory address over garbage collection - as far as I know this has never been demonstrated. The performance characteristics of REBOL's garbage collection are more consistent with mark-and-sweep, and there hasn't been any indication that it compacts or copies. Series reallocation on expansion does copy though. Plus, there is a bunch of indication that R3 isn't yet task-safe and that callbacks can choke on shared data too. Aside from that, your argument's good, and your conclusion more so. | |
Kaj: 21-May-2011 | Well, I wouldn't count on it, but indeed, what the extensions documentation specifies is that series can move when they are changed. It's all very vague, but if the collector doesn't compact as you say, it would be restricted to expanding series beyond the internally allocated memory region | |
Henrik: 26-May-2011 | Geomol, objects have series abilities now, so SELECT wouldn't work. | |
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. | |
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 | |
Ladislav: 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 - this is provably false | |
Ladislav: 6-Jun-2011 | http://www.rebol.net/wiki/Identity#Indices_of_series | |
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 | |
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 | With Option 3 that would change, since BACK from the head of the series would go out of bounds. REMOVE out of bounds would continue to be a noop. | |
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 | I noticed a funny thing, when inserting a series in the same series with the /only refinement. >> s: [a b c] == [a b c] >> length? skip s 2 == 1 ; makes sense >> insert/only s skip s 2 == [a b c] >> s == [[...] a b c] ; reference to the same series is shown this way, ok >> length? s/1 == 2 ; unexpected Wouldn't it be more logical, if that last result were 1? It's the same in R2. | |
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 | No I think it is not unexpected. Because when you insert new values into a series its internal positions is changing: | |
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. | |
Endo: 7-Jun-2011 | That is because, c is not a series pointing to another (in this case same) series. | |
Geomol: 7-Jun-2011 | Right. For blocks, inserting doens't change position of other indexes to same series. What I expect, is that the insert is from the index given, before the insert is carried out. Like: >> s: [a b c] >> insert/only s skip s 2 should result in [[c] a b c] , where the first element is a pointer to one before the end of s, not two before the end of s as we have today. | |
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.) :) | |
Geomol: 7-Jun-2011 | I understand, what happens, that it's a position in a series, I try to insert earlier in the same series. I just find it a bit confusing, it works as it does. Woldn't it be more logical, if it's the position + 1, that is inserted in such cases? I think, this looks strange: >> s: [a b c d e f g h] == [a b c d e f g h] >> insert/only s find s 'd == [a b c d e f g h] >> s/1 == [c d e f g h] It seems more logical to me, if it does this: >> s: [a b c d e f g h] == [a b c d e f g h] >> insert/only s next find s 'd == [a b c d e f g h] >> s/1 == [d e f g h] | |
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) | |
Geomol: 7-Jun-2011 | What if I want to insert the tail position of a series earlier in the same series? >> s: [1 2] == [1 2] >> insert/only s tail s == [1 2] >> s/1 == [2] >> insert/only s next tail s == [[...] 1 2] >> s/1 == [2] So that can't be done. | |
Endo: 7-Jun-2011 | So you could have a series which holds "pointers" to other some positions in another series, even a position in itself. | |
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'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. | |
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 | |
Gregg: 17-Jul-2011 | The original was written before MAP-EACH and the new COLLECT. Here is the source I have, updated to use those as the current version does, but with the last rule reverted to the original. Related cc reports: http://issue.cc/r3/1096 http://issue.cc/r3/690 split: func [ "Split a series into pieces; fixed or variable size, fixed number, or at delimiters" series [series!] "The series to split" dlm [block! integer! char! bitset! any-string!] "Split size, delimiter(s), or rule(s)." /into "If dlm is an integer, split into n pieces, rather than pieces of length n." /local size count mk1 mk2 ][ either all [block? dlm parse dlm [some integer!]] [ map-each len dlm [ either positive? len [ copy/part series series: skip series len ] [ series: skip series negate len ; return unset so that nothing is added to output () ] ] ][ size: dlm ; alias for readability collect [ parse/all series case [ all [integer? size into] [ if size < 1 [cause-error 'Script 'invalid-arg size] count: size - 1 size: round/down divide length? series size [ count [copy series size skip (keep/only series)] copy series to end (keep/only series) ] ] integer? dlm [ if size < 1 [cause-error 'Script 'invalid-arg size] [any [copy series 1 size skip (keep/only series)]] ] 'else [ ; = any [bitset? dlm any-string? dlm char? dlm] [any [mk1: some [mk2: dlm break | skip] (keep copy/part mk1 mk2)]] ] ] ] ] ] | |
Gregg: 17-Jul-2011 | Another bug has crept in somewhere along the way: series: skip series negate len The NEGATE messes up the skip of the already negative value, which breaks cases like this: >> split [1 2 3 4 5 6] [3 2 2 -2 2 -4 3] == [[1 2 3] [4 5] [6] [5 6] [3 4 5]] | |
Gregg: 17-Jul-2011 | split: func [ "Split a series into pieces; fixed or variable size, fixed number, or at delimiters" series [series!] "The series to split" dlm [block! integer! char! bitset! any-string!] "Split size, delimiter(s), or rule(s)." /into "If dlm is an integer, split into n pieces, rather than pieces of length n." /local size piece-size count mk1 mk2 res fill-val add-fill-val ][ either all [block? dlm parse dlm [some integer!]] [ map-each len dlm [ either positive? len [ copy/part series series: skip series len ] [ series: skip series len ; return unset so that nothing is added to output () ] ] ][ size: dlm ; alias for readability res: collect [ parse/all series case [ all [integer? size into] [ if size < 1 [cause-error 'Script 'invalid-arg size] count: size - 1 piece-size: to integer! round/down divide length? series size if zero? piece-size [piece-size: 1] [ count [copy series piece-size skip (keep/only series)] copy series to end (keep/only series) ] ] integer? dlm [ if size < 1 [cause-error 'Script 'invalid-arg size] [any [copy series 1 size skip (keep/only series)]] ] 'else [ ; = any [bitset? dlm any-string? dlm char? dlm] [any [mk1: some [mk2: dlm break | skip] (keep/only copy/part mk1 mk2)]] ] ] ] ;-- Special processing, to handle cases where the spec'd more items in ; /into than the series contains (so we want to append empty items), ; or where the dlm was a char/string/charset and it was the last char ; (so we want to append an empty field that the above rule misses). fill-val: does [copy either any-block? series [[]] [""]] add-fill-val: does [append/only res fill-val] case [ all [integer? size into] [ ; If the result is too short, i.e., less items than 'size, add ; empty items to fill it to 'size. ; We loop here, because insert/dup doesn't copy the value inserted. if size > length? res [ loop (size - length? res) [add-fill-val] ] ] ; integer? dlm [ ; ] 'else [ ; = any [bitset? dlm any-string? dlm char? dlm] ; If the last thing in the series is a delimiter, there is an ; implied empty field after it, which we add here. case [ bitset? dlm [ ; ATTEMPT is here because LAST will return NONE for an ; empty series, and finding none in a bitest is not allowed. if attempt [find dlm last series] [add-fill-val] ] char? dlm [ if dlm = last series [add-fill-val] ] string? dlm [ if all [ find series dlm empty? find/last/tail series dlm ] [add-fill-val] ] ] ] ] res ] ] | |
Gregg: 17-Jul-2011 | split: func [ "Split a series into pieces; fixed or variable size, fixed number, or at delimiters" series [series!] "The series to split" dlm [block! integer! char! bitset! any-string!] "Split size, delimiter(s), or rule(s)." /into "If dlm is an integer, split into n pieces, rather than pieces of length n." /local size piece-size count mk1 mk2 res fill-val add-fill-val ][ either all [block? dlm parse dlm [some integer!]] [ map-each len dlm [ either positive? len [ copy/part series series: skip series len ] [ series: skip series negate len ; return unset so that nothing is added to output () ] ] ][ size: dlm ; alias for readability res: collect [ parse/all series case [ all [integer? size into] [ if size < 1 [cause-error 'Script 'invalid-arg size] count: size - 1 piece-size: to integer! round/down divide length? series size if zero? piece-size [piece-size: 1] [ count [copy series piece-size skip (keep/only series)] copy series to end (keep/only series) ] ] integer? dlm [ if size < 1 [cause-error 'Script 'invalid-arg size] [any [copy series 1 size skip (keep/only series)]] ] 'else [ ; = any [bitset? dlm any-string? dlm char? dlm] [any [mk1: some [mk2: dlm break | skip] (keep/only copy/part mk1 mk2)]] ] ] ] ;-- Special processing, to handle cases where the spec'd more items in ; /into than the series contains (so we want to append empty items), ; or where the dlm was a char/string/charset and it was the last char ; (so we want to append an empty field that the above rule misses). fill-val: does [copy either any-block? series [[]] [""]] add-fill-val: does [append/only res fill-val] case [ all [integer? size into] [ ; If the result is too short, i.e., less items than 'size, add ; empty items to fill it to 'size. ; We loop here, because insert/dup doesn't copy the value inserted. if size > length? res [ loop (size - length? res) [add-fill-val] ] ] ; integer? dlm [ ; ] 'else [ ; = any [bitset? dlm any-string? dlm char? dlm] ; If the last thing in the series is a delimiter, there is an ; implied empty field after it, which we add here. case [ bitset? dlm [ ; ATTEMPT is here because LAST will return NONE for an ; empty series, and finding none in a bitest is not allowed. if attempt [find dlm last series] [add-fill-val] ] char? dlm [ if dlm = last series [add-fill-val] ] string? dlm [ if all [ find series dlm empty? find/last/tail series dlm ] [add-fill-val] ] ] ] ] res ] ] | |
BrianH: 19-Jul-2011 | I liked Carl's idea of a SPLIT function that takes a series and returns the series from the head to the offset, and from the offset to the end. Like this: split: func [series [series!]] [reduce [copy/part head series series copy series]] At most, add a option to control the copying. Then have a seperate function split on a delimeter, another split into a number of parts, etc. | |
Gregg: 19-Jul-2011 | How could this be made clearer then? Split a series into pieces; fixed or variable size, fixed number, or at delimiters Did you ever look at the docs for it? http://www.rebol.com/r3/docs/functions/split.html | |
Gregg: 19-Jul-2011 | It could be called SPLIT-SERIES I suppose, but I don't think it helps. | |
BrianH: 19-Jul-2011 | The non-dialected behaviors seem simple enough (for the purposes of discussion I've read the docs). The problem is in the dialect, especially these: - "Negative values can be used to skip in the series without returning that part:" Why not use a 'skip keyword for that? - "Note that for greater control, you can use simple parse rules:" Which ones? It really is a dialect, but the language is not confusing (first case) and not well defined (second case). Using keywords would make the dialect easier to understand (and thus use), and potentially more efficient to implement using command dispatch. | |
Pekr: 4-Aug-2011 | I generally like /skip. Just recently I used find/skip - very usefull, as it treats series as a set of records. | |
Robert: 4-Aug-2011 | Trying to get back a result from an async callback to Rebol. This is the code I use: int cb_error = RL_CALLBACK(cbi); // check error if(cb_error==0){ printf("to_rebol_processor: R3 callback failed"); return false; } // let's access the result from the callback (string! for now) char *callback_result; RL_GET_STRING(cbi->result.series, 0, (void**)&callback_result); The problem is that I get back a (null) pointer for callback_result and not the string. | |
BrianH: 12-Oct-2011 | INVALID-UTF? returns the series at the position of the first invalid sequence. If it doesn't flag it returns none. | |
Marco: 26-Nov-2011 | wish for R3 / Topaz / Red / World: I wish that refinements would be totally reworked (not R2 compatible :( ). Current situation with some examples: view/new/title/offset/options win "Dialog" 20x20 'resize remove_last: func [{remove last (n) element(s) of a series} serie [series!] /n num [integer!] ][ num: any [num 1] remove/part skip tail serie negate num num ] append: func [{Appends a value to the tail of a series and returns the series head.} series [series! port!] value /only ][ head either only [ insert/only tail series :value ] [ insert tail series :value ] ] New situation with different syntax and default values: view win /new true /title "Dialog" /offset 20x20 /options 'resize remove_last: func [{remove last (n) element(s) of a series} series [series!] /n: 1 [integer!] ][ remove skip tail series negate n /part n ] append: func [{Appends a value to the tail of a series and returns the series head.} series [series! port!] value /part /only /dup ][ head insert tail series :value /part part /only only /dup dup ] Note that append could also be redifined as: #macro append [] [head insert tail] | |
Group: Core ... Discuss core issues [web-public] | ||
GrahamC: 21-Oct-2010 | Regarding order of function parameters ... eg. REPLACE target search replace /all /case /tail it's probably not as intuitive to read ... but if you had REPLACE search replace target /all /case /tail this would aid processing the output of other functions So, instead of replace some series of functions here which returns a string but I've got to end this stream with replace target I could do replace replace target some series of functions here which returns a string but I've got to end this stream with | |
Gregg: 21-Oct-2010 | Then you might want to change all the other funcs that take the target series as their first arg as well. I'm OK with the existing arg order. |
1201 / 1531 | 1 | 2 | 3 | 4 | 5 | ... | 11 | 12 | [13] | 14 | 15 | 16 |