World: r3wp
[Rebol School] Rebol School
older newer | first last |
BrianH 2-Jan-2009 [1178] | If you want to replace, clear the series before providing it. |
Steeve 2-Jan-2009 [1179] | ok but i'm not convinced by the interest to be able to insert in the middle of a serie. |
Steeve 3-Jan-2009 [1180] | ok but i''m not convinced by the interest to be able to insert in the middle of a serie |
BrianH 3-Jan-2009 [1181x6] | This trick only works if it is pervasively implemented and consistent. It is a cross-cutting language design issue. |
cross-cutting = Aspect-Oriented Programming term. | |
It means that function options of the same name should be implemented consistently and to whatever function applicable. | |
(in this case, that is what it means) | |
A REBOL example is the /only option. | |
The /only option means something different each time, but in general its usage is consistent: - Do the sensible thing by default. - Do the advanced thing when /only is chosen. Every function with an /only option behaves this way. | |
Steeve 3-Jan-2009 [1187x2] | where is it already used ? |
i mean /into | |
BrianH 3-Jan-2009 [1189x3] | In functions in R3, starting with COLLECT. |
It will be used in many functions, and natives. REDUCE and COLLECT /into get rid of chained inserts, for instance. It also reduces series copy overhead. It will be a big deal when we hahve rolled it out across the board. | |
hahve -> have | |
Steeve 3-Jan-2009 [1192] | ok |
BrianH 3-Jan-2009 [1193] | I think MOLD and FORM should get /into as well. |
Steeve 3-Jan-2009 [1194] | and reduce ? |
BrianH 3-Jan-2009 [1195x2] | I mentioned REDUCE and COLLECT already :) |
Sorry, the last two mentions of COLLECT I meant COMPOSE :) | |
Steeve 3-Jan-2009 [1197] | erf |
BrianH 3-Jan-2009 [1198] | It's been a long day. |
Steeve 3-Jan-2009 [1199] | i have problems with my connexion, see you laters, nite... |
BrianH 3-Jan-2009 [1200] | Good night. |
[unknown: 5] 3-Jan-2009 [1201] | If you guys get some good mezzanines please post them on my Mezzanine thread. http://www.tretbase.com/forum/viewtopic.php?f=8&t=30Also, if anyone wants to make the current ones posted more efficient please do. |
Gregg 3-Jan-2009 [1202] | If you're looking for HOFs, and other advanced information, check out Ladislav's articles: http://www.fm.tul.cz/~ladislav/rebol/ |
Sunanda 3-Jan-2009 [1203] | Or http://www.rebol.org/view-script.r?script=hof.r |
Geomol 3-Jan-2009 [1204] | REBOL is so nice, that if you miss some cool feature found in some other language, like the MAP function, you can make it in a line of code. We should add a wiki with such cool things from other languages, and how you do it in REBOL. |
Steeve 3-Jan-2009 [1205x4] | As someone stated, what about a mezzanine thread for new proposal and discussions... ? thinking about [fold] (aka reduce) , i don't know if it's really intersting to have it as mezzanine, cause it's really short: fold y [1 2 3 4][x: x + y] x: 0 repeat y [1 2 3 4][x: x + y] |
wrong: >>x: 0 >>foreach y [1 2 3 4][x: x + y] | |
[foreach] is our HHOF (higher higher order function) | |
map: func [ [throw] "Evaluates a block for each value(s) in a series and returns them as a block." 'word [word! block!] "Word or block of words to set each time (local)" data [block!] "The series to traverse" body [block!] "Block to evaluate each time" /into "Collect into a given series, rather than a new block" output [series!] "The series to output to" ] [ unless into [output: make block! either word? word [length? data] [divide length? data length? word]] head foreach :word data compose [output: (:insert) output (to paren! body)] ] >> map x [1 2 3 4][x + x] == [2 4 6 8] >> map [x y][1 2 3 4][x + y] == [3 7] >> map/into [x y][1 2 3 4][x + y][10 11 12] == [3 7 10 11 12] But still a problem with the output var collision | |
Gregg 3-Jan-2009 [1209x2] | There are mezz groups in various places, but it does't look like we have a group for it here. Feel free to start one. Maybe add a checklist as well, for final versions and prioritizing. In any case, FOLD is not necessary, but nice for those that want it. REBOL lives in many worlds. One world is for imperative-minded folks, that don't know or care about HOFs and such, another is those that do. |
fold: func [ ; i.e. Haskell foldl (fold left). Same as 'reduce in Python? series [series!] fn [any-function!] /with value "starting value; used as accumulator" ][ if not with [value: pick series 1 series: next series] foreach item series [value: fn value item] ] sum: func [block [any-block!]] [fold block :add] product: func [block [any-block!]] [fold/with block :multiply 1] sum-of-squares: func [block [any-block!]] [ fold block func [x y] [x * x + y] 0 ] | |
Steeve 3-Jan-2009 [1211x2] | still on map, should be faster with /into len: to integer! either word? word [length? data] [divide length? data length? word] either into [insert/dup output none len][output: make block! len] head foreach :word data compose [output: (:change) output (to paren! body)] |
(no need of to integer!) | |
BrianH 3-Jan-2009 [1213x9] | I think the original, functional-style FOLD would be more useful for REBOL, as the REBOL-style one has been covered by foreach. Perhaps it should be done as a function that takes a block and words and returns a function though. I am not familiar with the Haskel equivalent, but I'd be surprised if it doesn't return a function. |
Here's a version of MAP with the /into semantics and no variable capture problems. I had to add a local function, though it is only created once per call. Binding issues prevent the use of a literal function. While i was at it I added unset! handling like the R3 version. map: func [ [throw] "Evaluates a block for each value(s) in a series and returns them as a block." 'word [word! block!] "Word or block of words to set each time (local)" data [block!] "The series to traverse" body [block!] "Block to evaluate each time" /into "Collect into a given series, rather than a new block" output [series!] "The series to output to" ] [ unless into [output: make block! either word? word [length? data] [divide length? data length? word]] foreach :word data reduce [func [val [any-type!]] [ if value? 'val [output: insert output :val] ] to paren! body] either into [:output] [head :output] ] | |
Note that the tail is returned with /into, for chaining purposes. | |
I forgot an /only though - the insert is supposed to be insert/only for the right behavior. | |
I forget /only more than I would like :( | |
Note that the copy performed by the FOREACH is a bind/copy, not a copy/deep. This means that only any-words, blocks and parens are copied, all other types are just referenced, including the function. | |
I think path! types are also copied by bind/copy. | |
Definitely not list! types. | |
Janko, the REBOL equivalent of Haskell's filter is REMOVE-EACH. | |
Janko 3-Jan-2009 [1222] | I read where I left off yesterday, very interesting chat, BrianH, thanks for info on remove-each |
BrianH 3-Jan-2009 [1223] | I added the last MAP with the insert/only fix to DevBase. We'll see if it gets accepted. All we're missing now is fold. |
Janko 3-Jan-2009 [1224] | great! :) |
Steeve 3-Jan-2009 [1225x2] | just a thing Brian... i don't like how map evolved. It lost his simplicity and inner speed. Some gain like (either vs to-block) have been over rated. some other bringing major speed regression have been under rated. i prefer the throw of an error during initialisation (ie. if find word 'output) instead of using the tricks of the embedded builded function. |
perhaps we should have 2 distinct foreach block or 2 distinct functions (map and map-into) | |
BrianH 4-Jan-2009 [1227] | We would have had to add the function anyway, for the the unset! screening we need for compatibility. And using the word 'output is not an error, so treating it as an error is inappropriate. |
older newer | first last |