AltME groups: search
Help · search scripts · search articles · search mailing listresults summary
world | hits |
r4wp | 1023 |
r3wp | 10555 |
total: | 11578 |
results window for this page: [start: 10101 end: 10200]
world-name: r3wp
Group: !REBOL3 GUI ... [web-public] | ||
Pekr: 5-Jan-2010 | BrianH: there are more changes planned, no? Like adding layers, etc. Henrik summed it up somewhere, maybe he can repost. And as far as I remember - the changes might influence your code, so I am not sure if it is good to do any GUI related work in recent VID state ... | |
Pekr: 6-Jan-2010 | I just found Henrik's summary. I think it is the post I had in mind: --------------------------------------------- Indeed VID3.4 is far from done. You can probably use it for a few things, like getting a name from a user in a text field or submit a very simple form, but not much more than that. To reiterate the state of the UI: - No unicode yet in graphics (when Cyphre gets around to it). - Resizing acts like a drunken sailor. (Carl) - Skin is not published. (Me) - Style tagging is not implemented. (Carl) - Reasonable requesters are not yet implemented. (Carl or me) - Layers are not yet implemented. (Carl) - Guides are not yet implemented. (Carl) - Better font rendering. We are not taking advantage of what AGG can do. (Cyphre again) - Event system is from Gabriele's VID3. (Carl) - Many features are untested, like drag&drop. (Me, I guess) - Proper material management for skin. (Me). - Many styles are not implemented, especially lists (Me). - More elaborate animation engine (Carl or Me). - Form dialect (Carl talked about this). - More/better icon artwork (Me). Plus, Maxim has some ideas for DRAW, to greatly speed up rendering, but I don't know if they can be implemented. The overall design of the GUI engine is very good. Whenever a change or addition is made, you alter 3-5 lines of code in one place, and it works. I doubt the entire engine will be rewritten. You won't see GUI bug reports in Curecode for a while. There could easily be 2-300 reports, once we get to that point. My work regarding skins is rather big: I need to work out the basic styles first, so we have a reasonable way to build compound styles. These are being done using a very simple, but pixel accurate GUI using plain colored surfaces. This is easier for testing out, as draw blocks are small, but as Pekr likes to complain: They are not pretty to look at. Once the real skin goes into place, the draw blocks will grow a lot. I would love to see a low-level GOB management dialect, like Gabriele's MakeGOB. | |
Pekr: 6-Jan-2010 | Henrik and BrianH should agree upon what do we mean by "layers", as Henrik claims they need to be done, whereas BrianH claims we have them already :-) | |
Graham: 6-Jan-2010 | Did you want to do that? revise the viewtop sources? | |
Pekr: 8-Jan-2010 | I digged following from Max in the past: --------------------------------- My pet peeve about R3 view is that we still don't have access to the actual AGG elements directly within rebol. We still have to go through a clumsy interface called draw dialect. The dialect is fine (great actually) for initialisation, but after that, its not adapted to actual manipulation of what is going on inside, you have to go trough a rebol -> agg convertion stage at each refresh. It's not the speed, it's the fact that it's complicated cause you have to create "virtual" draw components and then assemble them on the fly reducing blocks and stuff. I'd love to be able to do: a: draw [circle 30x30 15] a/radius: 30 a/offset: 100x100 show a If graphic elements where first class datatypes, we could completely ignore the gobs, and build real canvases, uber fast. Another example, more appropriate: ; this draws a box... draw [s: polygon 10x10 30x10 30x-30 10x-30] ; make it a house outline insert at s/vertices 4 20x-40 ; raise the "roof" s/vertices/4/y: -50 The problem is that to edit draw blocks, you have to create a slew of things before creating the draw block, then you have to store references to all of those things somewhere, everytime you want to add a "dynamic" attribute its pretty tedious. The first-class gel datatype would allow AGG to edit its internals directly using binary C code through its accessors. no need to go through rebol funcs and reducing blocks, etc. The use of "show a" above could intrinsincally know that it only needs to refresh the region that this element affects, just like all graphic cards do when evaluating the graphic pipe rendering. So many things like flash games which become soooo heavy in AGG would be real-time and use much less CPU resouces. in most games only a small part of the canvas really changes interactively. | |
Henrik: 8-Jan-2010 | no, that doesn't have anything to do with GOBs. those are problems with DRAW. GOBs are about as small and lightweight as they can be. How they are used by the system is a different matter. | |
Graham: 15-Jan-2010 | My first gui script http://rebol.wik.is/Rebol3/R3_GUI/Sendfax.r I'd like to have the output from net-log appearing in the area .. but I can only get it do that once and then nothing ... | |
Pavel: 19-Jan-2010 | Hinting have mainly influence in rendering of "Stems" simplified it means all vertical lines will be the same width in my Ailal font I,L,M letters at some resolution. Having nothing to do with spaces between letters. Kerning is what is for inter letters spaces bussiness. | |
Henrik: 24-Jan-2010 | Carl's original goal for the GUI was to make it so a child could use it. We should not deviate from that goal. That's part of what Rebrowse is meant to do. I don't want to risk a forking of the GUI work. | |
Henrik: 24-Jan-2010 | Most of VID's serious issues come down to event handling (solvable now) and incompleteness (also solvable, just a bunch of hard work) and missing features, like keyboard navigation (already solved that). The VID extension kit makes VID much more scalable, simply by finishing the work that Carl set out to do. It's easier to write large apps because styles are more uniform, and you have more powerful features and adherence to face accessors, rather than relying on face hacking. Building those features into V3.4 by default, and you have a killer UI system without sacrificing usability. | |
Pekr: 24-Jan-2010 | Max - so what do you propose for the kernel, to not be 1.5 and 3, but 1, 2, 3? :-) | |
Ashley: 25-Jan-2010 | I've spent a bit of time going over R3/View and believe it now has all the "building blocks" required to build a modern/fast gob! based GUI. The amazing thing is that these building blocks are the 10 natives that View adds [to Core]. They are: gob! caret-to-offset cursor draw effect map-event map-gob-offset offset-to-caret show size-text With these 10 natives (gob! is actually a type!) we should be able to construct simple but powerfull gob!-based GUIs with a smaller mezz footprint than R2. My preliminary conversion of RebGUI to R3 seems to take about 50% the code to do the same thing [compared to R2] ... very promising at first glance. To get a feeling for how tight the code can be the next post is the entire [skeleton] source of a working gob!-based GUI. | |
Ashley: 25-Jan-2010 | ctx-rebgui3: make object! [ cursors: make object! [ app-start: 32650 hand: 32649 help: 32651 hourglass: 32650 arrow: 32512 cross: 32515 i-shape: 32513 no: 32648 size-all: 32646 size-nesw: 32643 size-ns: 32645 size-nwse: 32642 size-we: 32644 up-arrow: 32516 wait: 32514 ] colors: make object! [ page: white edit: white text: black true: leaf false: red link: blue theme: [165.217.246 0.105.207 0.55.155] outline: [207.207.207 160.160.160 112.112.112] ] metrics: make object! [ cell: 4 gap: cell * 2 line: cell * 5 margin: cell * 4 margin-size: as-pair margin margin radius: 2 ] ; Private functions set 'make-gob make function! [[ spec [block!] ; offset, size and one or more attribute/value pairs /data object /local size text gob axis ][ size: spec/2 if any [negative? size/x negative? size/y] [ text: select spec 'text all [block? text text: first find text string!] size: 8x4 + size-text make gob! compose [size: 9999x9999 text: (text)] all [negative? spec/2/x spec/2/x: size/x] all [negative? spec/2/y spec/2/y: size/y] ] gob: copy [] ; attributes are (text, color, effect, image and draw) foreach [attribute value] spec [ switch attribute [ box [ attribute: 'draw value: compose [ pen (get value/1) line-width 1 fill-pen (get value/2) box 0x0 (spec/2 - 1x1) (metrics/radius) ] ] pill [ attribute: 'draw axis: either spec/2/x >= spec/2/y [2] [1] value: compose/deep [ pen (colors/outline/3) line-width 1 grad-pen linear (spec/2/:axis * .1) (spec/2/:axis * .9) (all [axis = 2 90]) [(colors/outline/1) (white) (colors/outline/1)] box 0x0 (spec/2 - 1x1) (metrics/radius) ] ] ] append gob reduce [attribute value] ] spec: gob gob: make gob! compose [offset: spec/1 size: spec/2 (to set-word! spec/3) spec/4 data: (make object! any [object copy []])] foreach [attribute value] skip spec 2 [ append gob make gob! compose [offset: 0x0 size: spec/2 (to set-word! attribute) value] ] gob ]] ; Public functions set 'display make function! [[ title spec /local gob xy max-x max-y left-to-right? after-count after-limit here arg append-widget widget last-widget word action handler size text color ][ xy: metrics/margin-size max-x: xy/x max-y: xy/y left-to-right?: true after-count: 1 after-limit: 9999 gob: make gob! compose [text: (title) data: (make object! [])] append-widget: make function! [[][ unless widget [exit] unless handler [ handler: compose/deep [on-down: make function! [[event][(action)]]] ] append gob switch widget [ bar [ make-gob compose [(xy) (as-pair max-x - metrics/margin 1) color (colors/outline/3)] ] button [ all [none? size size: 15x5] make-gob/data compose/deep [(xy) (size * metrics/cell) pill none text [center (text)]] handler ] text [ all [none? size size: 15x5] make-gob/data compose/only [(xy) (size * metrics/cell) color (white) text (text)] handler ] ] last-widget: last gob/pane ; 1st reverse item? unless left-to-right? [ last-widget/offset/x: last-widget/offset/x - last-widget/size/x ] xy: last-widget/offset ; max vertical size max-y: max max-y xy/y + last-widget/size/y ; horizontal pos adjustments all [ left-to-right? xy/x: xy/x + last-widget/size/x max-x: max max-x xy/x ] ; after limit reached? either after-count < after-limit [ ; spacing xy/x: xy/x + either left-to-right? [metrics/gap] [negate metrics/gap] ++ after-count ] [ xy: as-pair metrics/margin max-y + metrics/gap after-count: 1 ] all [:word set :word last-widget] word: widget: action: handler: size: text: color: none ]] parse reduce/only spec [after bar button handler return reverse rich text] [ any [ opt [here: set arg paren! (here/1: do arg) :here] [ 'return ( append-widget xy: as-pair metrics/margin max-y + metrics/gap left-to-right?: true after-limit: 9999 ) | 'reverse ( append-widget xy: as-pair max-x max-y + metrics/gap left-to-right?: false after-limit: 9999 ) | 'after set arg integer! ( ; return unless this is first widget if widget [ append-widget xy: as-pair metrics/margin max-y + metrics/gap ] after-count: 1 after-limit: arg ) | 'handler set arg block! (handler: arg) | 'rich set arg block! (text: arg) | [set arg integer! | set arg pair!] (size: arg) | set arg string! (text: arg) | [set arg tuple! | set arg none!] (color: arg) | set arg block! (action: arg) | set arg set-word! (append-widget word: :arg) | set arg word! (append-widget widget: arg) ] ] ] append-widget gob/size: metrics/margin-size + as-pair max-x max-y gob/offset: system/view/metrics/work-size - gob/size / 2 append system/view/screen-gob gob show system/view/screen-gob ]] set 'undisplay make function! [[gob][ remove find system/view/screen-gob gob show system/view/screen-gob ]] ; Start global GUI event handler active-gob: none system/view/event-port: open [scheme: 'event] system/view/event-port/awake: make function! [[event /local evt gob][ evt: map-event event gob: evt/gob while [not object? gob/data] [gob: gob/parent] if all [event/type = 'move gob <> active-gob] [ attempt [active-gob/data/on-away event] active-gob: gob attempt [active-gob/data/on-over event] ] evt: to word! ajoin ['on- event/type] attempt [gob/data/:evt event] ]] ] | |
Cyphre: 29-Jan-2010 | Ashley, I can't see most of your problems when using r3-a96.exe Please try: do http://cyphre.mysteria.cz/tests/caret-test.r You should see it works correcty. The only problem I was able to repro is that the shortcuts b,i,u and nl aren't working...probably some 'regression' in newer builds as I remember it worked before. | |
Graham: 3-Feb-2010 | I was just curious to see how Gab's systemm worked .. and I tried %test.r but >> do %test.r Script: "Test vid" Version: none Date: none Script: "REBOL View System Functions" Version: none Date: none Script: "rewrite-tree function" Version: none Date: none Script: "Simple dialect to create/resize gobs" Version: none Date: none Script: "REBOL VID 3: Definition of FACE prototype object" Version: none Date: n one Script: "REBOL VID 3: Functions" Version: none Date: none Script: "REBOL VID 3: Events Handling" Version: none Date: none Script: "REBOL VID 3: Styles" Version: none Date: none ** Script error: cannot MAKE/TO map! from: none! ** Where: make either make handler parse parse-set-dialect make-styles catch eit her either applier do catch either either applier do ** Near: make map! style-spec/options | |
Graham: 5-Feb-2010 | Is there an easier way to do this than this? code-text-list: tight [ about: "List of selectable text lines with scrollbar using a monospaced font." facets: [ max-size: 150x3000 ] options: [ list-data: [block!] ] content: [ text-list-box :list-data :area-color options [ text-style: 'code ] scroller ] actors: [ on-init: [ if select face 'reactors [ extend face/faces/1 'reactors face/reactors ] ] on-set: [ set-face/list face/faces/1 arg ] on-get: [ get-face face/faces/1 ] ] ] | |
Ashley: 5-Feb-2010 | OK, a meta-gob to recreate R2 functionality (given that a gob! can only do one thing)? I understand why layout was a "face factory" under V2, just thought we'd naturally move to a "gob! factory" approach with R3. I'm not being critical, just trying to understand why we still need the concept of faces under R3. | |
Henrik: 5-Feb-2010 | Ashley, "just trying to understand why we still need the concept of faces under R3." - The role of faces in R3 are just what they were in R2, a collection of features and functions inside an object, but instead of the underlying View system being closed, they are now linked to a fixed set of GOBs, that we eventually can extend with all sorts of features. So: R2: Layout -> Face tree -> View R3: Layout -> Face tree -> GOBs -> View Faces are what are generated by the layout. So the "face factory" is still needed and styles are the "molds" or prototypes. Within the face factory, the GOB factory exists. I would assume this separation makes HW acceleration or replacing GOBs with a different structure, much easier later. GOBs are redrawn using DRAW-FACE and that is handled inside the styles. Styles use resources like fonts, colors, materials and standard draw blocks. This eventually helps skinning and abstracts these things away from the styles themselves. The obscure FEEL object is replaced with a set of on-* actors that are run at specific times in specific sequences during runtime. They are more fine grained, so you can determine what you want to do, for example during various stages of face initialization. The relationship between the layout dialect and faces is a bit different than under R2: you can't access the whole face in R3, only facets. For example the GOB itself, is not a facet and neither are internal states. So in order to change a deeper element of a style, you need to create a new style. This seems cumbersome, but is badly needed for large layouts, where we are semantically separating appearance from purpose. VID allowed this to be an organic mess. We may figure out a way to make creating derivative styles a bit easier. | |
Henrik: 5-Feb-2010 | to be curious, what do you need the comment for? | |
Pekr: 5-Feb-2010 | :-) So when the work on GUI is supposed to be restarted? Do we wait for its inclusion into HostKit section? | |
Pekr: 5-Feb-2010 | I was just reading about upcoming new Facebook facelift ... and following the discussion I found out, that one person suggests very cool Facebook client done in Silverlight. I needed to download SL beta 4. Then I tried that mighty app. Guy, I can tell you - we can do it in View anyday. Its not any faster, any better, and I would really like to see the ugly code behind the app. My long time suggestion to popularise View is to wrap known services - gmail, FB, etc. E.g. especially on my Winmobile, ther's a FB client done by MS, and you can't even read more than 1 reaction to your post. I imediatelly can imagine Winmobile client in R3 :-) Here's the screenshot - http://xidys.com/pekr/facebook-silverlight.jpg | |
Group: Core ... Discuss core issues [web-public] | ||
Ladislav: 4-Nov-2010 | Brian, in http://www.curecode.org/rebol3/ticket.rsp?id=1744&cursor=2 you wrote: "We already have local THROW and RETURN" If we do, I must have missed them, knowing only the global variants. Can you point me to them? | |
Sunanda: 5-Nov-2010 | There may be better ways: first do to-path reduce ['a get 'd get 'e] | |
BrianH: 5-Nov-2010 | You were focusing on localiity of where the code was written, and I was talking of locality in the code that the flow of execution goes through at runtime. For instance, #1744 makes it difficult for non-local-definition code to do man-in-the-middle attacks or spoofing, making it useful for secure mezzanine control flow functions. But #1518 prevents you from being able to pass THROW/name through unknown code at all, making it useless for making mezzanine control flow functions at all. Fixing #1518 is what we do to make #1743 possible, and once #1520 is implemented then the arms race will be over, everything else could be mezzanine or user-defined. | |
Ladislav: 14-Nov-2010 | switch: func [ "Selects a choice and evaluates what follows it." value "Value to search for." cases [block!] "Block of cases to search." /default case "Default case if no others are found." ][ either value: select cases value [do value] [ either default [do case] [none]] ] replace SELECT by SELECT/CASE | |
Anton: 17-Nov-2010 | That functionality is pretty easy to by evaluating the word inside the condition block yourself. eg. while [do cb] [...] so I don't think it's really necessary. | |
Steeve: 3-Dec-2010 | Nice challenge. To find the smallest mezz to do so | |
GrahamC: 3-Dec-2010 | It's a GPL app to do drug prescribing and drug interactions .. I am just using their database | |
BrianH: 3-Dec-2010 | Once the database is in memory you don't necessarily need to do set operations (SQL select). You can do iterative operations much more quickly. | |
GrahamC: 3-Dec-2010 | so at present I think I generate all possible combinations and check to see if they're in the same set and if not do the sql query | |
BrianH: 10-Dec-2010 | std::sort seems to do really well. | |
BrianH: 10-Dec-2010 | Interesting. It's been a long time since I used C++ (there were no standard libraries then). It never occured to me that someone would use an unstable sort algorithm without checking first whether it would be safe to do so. I must have missed that in college. | |
Steeve: 15-Dec-2010 | Searching for an optimal (small and fast) implementation of the following pattern. * Swap two subsets inside a serie. input block: [4 5 6 1 2] (5 values) Starting index of the 2nd subset inside the block: 4 Output: [ 1 2 4 5 6] Easy to do in plain Rebol right ? But here's the trouble, It must be memory safe. You're not allowed to do any memory allocation. You're can only swap values inside the block. And the number of swaps should be optimal. (no sort, no parse, no copy/make/insert/append/change) | |
Sunanda: 15-Dec-2010 | Just for starters.....This does it with 12 XORs (three per swap). But the tricky bit may be pre-computing the from-list and to-list mapping ;; function to do the swap swap-items: func [ data [block!] from-list [block!] to-list [block!] /local ind1 ind2 ][ for n 1 length? from-list 1 [ ind1: from-list/:n ind2: to-list/:n data/:ind1: xor data/:ind1 data/:ind2 data/:ind2: xor data/:ind1 data/:ind2 data/:ind1: xor data/:ind1 data/:ind2 ] return data ] ;; Sample run block: [4 5 6 1 2] probe swap-items block [1 2 1 1] [3 4 5 2] [1 2 4 5 6] | |
Sunanda: 16-Dec-2010 | I've written some very clunky code that I'd be ashamed to post as a solution. But I can offer you an algorithm that acheives the effect in N-1 swaps at most where N is the sum of the lengths of the two sequences. It's the more-or-less same algorithm used by Andreas. Here's how it works. Given these two sequences: a b c 1 2 3 4 5 6 7 Step1: cyclically rotate the longer sequence M times, where M is the difference in length of the sequences. So in this case, we rotate 3 (7 - 4) times: a b c 4 5 6 7 1 2 3 Step2: swap the elements of the shorter sequence with the tail of the longer one: 1 2 3 4 5 6 7 a b c And it's done. The cycling in place is the tricky part. It can be done, but my code is just too ugly to share :( Andreas's bubble-to-front is an elegant approach to doing the cycling, but is not optimed to reduce the number of steps. It's a managable sub-problem that is a challenge to solve, so I am sure someone can do better than me :) | |
Ladislav: 27-Dec-2010 | In my opinion, to 'allow' INSERT, APPEND and CHANGE handle #[unset!] makes 'disallowing' POKE to do the same uncomfortable. | |
DideC: 8-Feb-2011 | Rebol [] make-obj: func [ "Créé un objet en sauvant son nom dedans." 'name "Nom de l'objet à créer." obj "Objet de base à instancier." spec "extension de l'objet de base." ] [ set name make obj append reduce [to-set-word 'obj-name to-string name] spec ] save-obj: func [ "Sauvegarde un objet selon son propre nom." 'obj "Objet à sauvegarder." /local name ] [ name: any [all [word? obj object? get obj get in get obj 'obj-name] join "objet" random 10000] save/all to-file join name ".r" get obj ] load-obj: func [ "Recharge un objet et l'intancie selon son propre nom s'il en a un." file "Nom du fichier à charger." /local obj ] [ if exists? file [ obj: load file probe bind next first obj obj probe get in obj 'list all [in obj 'obj-name set to-word get in obj 'obj-name obj] ] obj ] task: make object! [ list: copy [] add: funct [t [block!]] [ append list t ] save: does [ save-obj self ] run: does [ do list ] ] make-obj task1 task [] task1/add [a: 0 a: a + 1] task1/add [print a] task1/run task1/save task1: none load-obj %task1.r task1/run | |
Dockimbel: 8-Feb-2011 | Anyway, binding information is lost during serialization (MOLD or MOLD/ALL), so if you want to get back bindings from serialized code, you need to manually ensure that the binding will be reconstructed as expected. That's achieved easily in your simple example using the SAVE / DO combination, but it can get much more complex in other cases and could require a lot of additional code. | |
Dockimbel: 8-Feb-2011 | do load does not work with the serialized form (I tried it)?" I'm not sure to understand what you mean there. SAVE/ALL uses MOLD/ALL to serialize values, so binding information is not preserved. If you want to restore correct binding in a object! serialized using /ALL format, you need to write some code to walk through object's functions body blocks and bind object's words explicitely using BIND. | |
Dockimbel: 8-Feb-2011 | This would be similar to what MAKE does on an object's spec block! but a bit smarter as you need to dive into function! values (MAKE doesn't do that AFAICT). You need to see the distinction between "unevaluated code" (source form) and "evaluated code" (reduced form) to get a clear picture on this issue. | |
BrianH: 8-Feb-2011 | Nested bindings are faked using a procedural process in REBOL. Serialized syntax is declarative, and there isn't a reference to the bindings in that syntax. It would be possible to make a serialized syntax that includes binding references, and the proposal to do that is called Rebin. | |
BrianH: 22-Feb-2011 | All trailing pipe characters? Do you want to remove any other characters other than | ? | |
BrianH: 22-Feb-2011 | So you might need to do a bit of tweaking for the R2 version, but it's a start. | |
BrianH: 23-Feb-2011 | Here's a working version: map-each: func [ "Evaluates a block for each value(s) in a series and returns them as a block." [throw catch] '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 [any-block! any-string!] "The series to output to" ; Not image! /local init len x ][ ; Shortcut return for empty data either empty? data [any [output make block! 0]] [ ; BIND/copy word and body word: either block? word [ if empty? word [throw make error! [script invalid-arg []]] copy/deep word ; /deep because word is rebound before errors checked ] [reduce [word]] word: use word reduce [word] body: bind/copy body first word ; Build init code init: none parse word [any [word! | x: set-word! ( unless init [init: make block! 4] ; Add [x: at data index] to init, and remove from word insert insert insert tail init first x [at data] index? x remove x ) :x | x: skip ( throw make error! reduce ['script 'expect-set [word! set-word!] type? first x] )]] len: length? word ; Can be zero now (for advanced code tricks) ; Create the output series if not specified unless into [output: make block! divide length? data max 1 len] ; Process the data (which is not empty at this point) until [ ; Note: output: insert/only output needed for list! output set word data do init unless unset? set/any 'x do body [output: insert/only output :x] tail? data: skip data len ] ; Return the output and clean up memory references also either into [output] [head output] ( set [word data body output init x] none ) ] ] | |
Oldes: 7-Mar-2011 | No.. it doesn't... it's possible to DO a script which has some sort of junk, but not LOAD. | |
james_nak: 11-Mar-2011 | Sorry, about these delays. I was on on an online session. So When I use parse-xml+ on my xml string, I get the following: [document [version none encoding none standalone none doctype none pubid none sysid none subset none ] [["TTL_Status" none ["^/^-" ["INPUT_TTLS" none ["^/^-^-" ["TTL_IN" ["value" "0"] [{ ^-^-^-} ["status" ["value" "1"] none] "^/^-^-"]] "^/^-^-" ["TTL_IN" ["value" "1"] [{ ^-^-^-} ["status" ["value" "1"] none] "^/^-^-"]] "^/^-"]] "^/^-" ["OUTPUT_TTLS" none ["^/^-^-" ["TTL_OUT" ["value" "0"] [{ ^-^-^-} ["status" ["value" "0"] none] "^/^-^-"]] "^/^-"]] "^/"]]]] I know it's not that readable... Then I run xml-to-object on that block and get: o: xml-to-object blk where block is the output of parse-xml+ above. probe o [document: make object! [TTL_Status: make object! [INPUT_TTLS: make object! [TTL_IN: make block! reduce [ make object! [status: make object! [value?: "" value: "1"] value: "0"] make object! [status: make object! [value?: "" value : "1"] value: "1"] ]] OUTPUT_TTLS: make object! [TTL_OUT: make object! [status: make object! [value?: "" value: "0"] value: "0"]]] version: none encoding: none standalone: none doctype: none pubid: none sysid: none subset: none ]] So this is where my ignorance leaves me. How do I make "o" into a an object where all the nested objects become real objects and don't remain as blocks? | |
Geocaching: 16-Mar-2011 | Also, why the following code does not work: >> rebcode: copy [] == [] >> append rebcode to-word "sine/radians" == [sine/radians] >> append rebcode 0.5 == [sine/radians 0.5] >> do rebcode ** Script Error: sine/radians has no value ** Near: sine/radians 0.5 | |
Geocaching: 16-Mar-2011 | Thanks rebolek... interesting But what do you mean with "It's possible to get your desired behaviour with #2, but it's slow." | |
Rebolek: 16-Mar-2011 | I mean this: >> dt [loop 1000 [c: copy [] append/only c 'sine/radians append c 0.5 do c]] == 0:00:00.002512 >> dt [loop 1000 [c: copy [] append/only c load "sine/radians" append c 0.5 do c]] == 0:00:00.035299 In second case, to convert from string! to path!, string must be loaded first and as you can see it's about 14x slower in this rough test. | |
Geocaching: 17-Mar-2011 | Hello Just a basic question: when creating or resetting a string! or a block!, should we do a: "" b: [] or is better to do a: copy "" b: copy [] I tend to do the second way... Does it make a difference? If yes, which way is better. Thanks | |
Geocaching: 17-Mar-2011 | The bahaviour of my-code-a is confusing... What could be the point to do a: "" then? | |
Group: !REBOL3 Proposals ... For discussion of feature proposals [web-public] | ||
BrianH: 3-Nov-2010 | But SECURE doesn't protect from those kind of security issues anyways, so this may be not a problem that we have to worry about here. However, normally the security prompt will protect against this kind of thing, and the whole point of SECURE/do is to get rid of that prompt. | |
Maxim: 3-Nov-2010 | though in most cases SECURE/do would be used to restrict what *your* code is allowed to access ... | |
BrianH: 3-Nov-2010 | Full sandboxing would require running in a separate task, calling a script by IMPORT/no-lib/no-user/isolate instead of DO, and providing a whole set of safe words and wrapper functions for the script to use. But many aspects of the existing system are designed with this in mind. | |
BrianH: 3-Nov-2010 | All you need to do to sandbox some code is isolate it and give it its own lib and user contexts. | |
BrianH: 3-Nov-2010 | The SANDBOX function wouldn't then need to do anything custom to the user context that the script it is running is using. All it would need to do is create a safe system object, create an object that references that object using the 'system word, and set the lib and security settings to those provided as arguments to the SANDBOX function. | |
BrianH: 4-Nov-2010 | #1521 would be better to do as a separate function (perhaps RECOVER). | |
PatrickP61: 4-Nov-2010 | I would be just thrilled to see something like PROBE/SOLVE I have trouble "understanding" how to read rebol code. I'm getting there, but still I make mistakes. I would love to see a "step by step" breakdown of some rebol code. I'll give you a good metaphor: Remember Algebra, with parethasis and the steps you took to solve a problem: ( (a * 2) + (b / 3) ) / 5 Then you substituted for your variables step by step and solved the problem. I'd love to have rebol do something like that. So instead of one line like PROBE, you could get several lines, that show how the function was evaluated to arrive at the final result. Maybe TRACE does this? All in all, I'd like more debugging tools, or at least some expanded documentation on how to debug rebol code faster! Thanks | |
Maxim: 8-Nov-2010 | Pat, remember that you can replace the function building mezz code like funct and func. though its not for novice users, since you do have the source when you 'SOURCE these builders, it can be quite easy to tweak them so they do a few things more... like add a little break point at the end of each func and probe all the collected words, in FUNCT. with a global word you could control if this tracing occurs, just by setting it to true or false, dynamically. | |
Andreas: 9-Nov-2010 | That has nothing to do with inner functions. | |
Andreas: 9-Nov-2010 | Of course, at this point you don't need to use an inner function at all, you just use bind + do. | |
Andreas: 9-Nov-2010 | All you have to do is construct a correct inner function, instead of an erroneous one. | |
Andreas: 9-Nov-2010 | Which is hypothetical as it is easy to show there are no such cases. So inner functions have nothing to do with it. | |
BrianH: 9-Nov-2010 | So even the FOREACH workaround would be enough to prompt a change now. For that matter, the most recent module system rewrite was specifically for that reason. The new module system doesn't do anything that the pre-108 rewrite didn't do, but it is easier to use. Easy by default is the top priority. | |
BrianH: 9-Nov-2010 | The only reason definitional-only might be chosen is because it is easier to understand than the other models. That alone might trump the places where it still doesn't work. I hope not, because the "option to not rebind RETURN and EXIT" is really simple to specify and much easier to do than the workarounds that you have to do if you don't have that option, workarounds like your BIND + DO, especially when you consider 'self issues that prevent you from using objects for this kind of thing (hence the FOREACH). | |
BrianH: 10-Nov-2010 | You missed one thing: To make PARSE rules task-safe, we should be moving them into function blocks anyways. And recursion-safe, for some really obscure tricks that the new PARSE IF operation lets us do, but the task-safe thing will come up more often. | |
BrianH: 10-Nov-2010 | So the "return from PARSE rules" thing will only be a problem for R2-style code. Once we do all the other tricks to make it R3-style, we get proper behavior for free :) | |
Ladislav: 11-Nov-2010 | For an even more interesting thing - a definitional catch/throw pair (which can be ported to R2) see the Exception_proposals article. Advantage: you do not have to use any name, yet, only the right throw is caught. | |
Maxim: 11-Nov-2010 | its just my bumbling appraisal so far, because it seems to me that you don't need to redefine and contextualize everything within your mezz code... but I do say I'm novice at this subject. (I'm trying hard to completely "get" it/ | |
Maxim: 11-Nov-2010 | yes, but the error document tries to illustrate it too, and I didn''t see it as plainly as I do now. | |
BrianH: 11-Nov-2010 | The reason we can get rid of dynamic returns in R3 is because the critical stuff that we used to do with dynamic returns in R2 is *necessarily* handled by dynamic breaks in R3, so dynamic returns are no big loss. | |
BrianH: 11-Nov-2010 | Definitional returns or escapes rely on lexical scope. If you don't have lexical scope, you don't have the ability to do definitional. So what PARSE needs is for the top-level BREAK to be dynamic. And if one level is dynamic, we are better off with all levels being dynamic, at least for the same escape function. Same goes for definitional. | |
BrianH: 11-Nov-2010 | Which is not the same as PARSE [(return)], but PARSE doesn't pay attention to the bindings of the keywords in its rules, just those of the rule names. And in the productions (parens) PARSE can't do any rebinding at all because it can't assume that BREAK is referring to the same function. | |
BrianH: 11-Nov-2010 | It is becoming abundantly clear that there is more and more need for a comparison section that shows the strengths of dynamic vs. definitional, because people seem to not understand that there are ceratin classes of code and algorithms (parsing, for instance) that can't be expressed with strict lexical scoping. You are giving up a lot when you go definitional, so that better stuff not be as important in the context where you do it. | |
BrianH: 11-Nov-2010 | And I can use those same proofs to apply to other algorithms with similar characteristics, and *know* that you gain some abilities with definitional scope, and lose others. This is why I know that Ladislav's DO-ALL is a loop, and so not wanting BREAK to apply to it is more of an opinion than something inherent in its nature. But that doesn't mean that the need for that is less. | |
BrianH: 11-Nov-2010 | Please don't take my mentioning of downsides as being a statement of opinion or some kind of taking sides. I only mention them because they are real, and must be considered when picking a certain strategy. Both approaches have plusses and minuses. If you want to make a rational choice then you need to know the issues - otherwise you are just being a fanboy. For instance, I picked the definitional side for returns, without the need for a fallback to dynamic, because of a rational evaluation of the algorithmic style of R3's functions. And it wasn't until I remembered that the tasking issues had already removed the advantages that dynamic scoping has over lexical scoping - we just can't do that stuff as much anymore, so it doesn't matter if we don't try. The same goes for loops, but to a lesser extent - loops aren't affected as much by tasking issues so we can still do code that would benefit from dynamic breaks, but it still might be a worthy tradeoff to avoid needing an option (since we have no such option). But for THROW, especially THROW/name, there are things that you can do with dynamic throw that you *can't* do with definitional, and those things would have great value, so it's a rational choice to make the tradeoff in favor of dynamic. | |
BrianH: 11-Nov-2010 | Well it comes down to this: Functions are defined lexically. Though they are called dynamically, they aren't called until after they have already been bound, definitionally. But as a side effect of tasking, those bindings are stack-relative, and those stacks are task-local. But random blocks of code outside of functions are bound to object contexts, and those are *not* task-local. So that means that the old R2 practice of calling shared blocks of code is a really bad idea in R3 if any words are modified, unless there is some kind of locking or synchronization. This means that those blocks need to be moved into functions if their code is meant to be sharable, which means that at least as far as RETURN and EXIT are concerned, they can be considered lexically scoped. The advantage that we would get from being able to call a shared block of code and explicitly return in that block is moot, because we can't really do that much anymore. This means that we don't lose anything by switching to definitional code that we haven't already lost for other reasons. At least as far as functions are concerned, all task-safe code is definitional. Loops are also defined lexically, more or less, and the rebinding ones are also task-safe because they are BIND/copy'd to a selfless object context that is only used for that one call and thrown away afterwards. And most calls to loops are task-safe anyways because they are contained in functions. However, the LOOP, FORALL, FORSKIP and WHILE loops do not rebind at the moment. We actually prefer to use those particular loops sometimes in R3 code because they can be more efficient than *EACH and REPEAT, because they don't have that BIND/copy overhead. Other times we prefer to use *EACH or REPEAT, in case particular loop fits better, or has high-enough repetitions and enough word references that the 27% overhead for stack-local word reference is enough to be more than the once-per-loop BIND/copy overhead. Since you don't have to move blocks into *loops* to make them task-safe, you can use blocks referred to by word to hold code that would be shared between different bits of code in the same function. This is called manual common subexpression elimination (CSE), and is a common optimization trick in advanced REBOL code, because we have to hand-optimize REBOL using tricks that the compiler would do for us if we were using a compiled language. Also, PARSE rules are often called from loops, and they are frequently (and in specific cases necessarily) referred to by word instead of lexically nested; most of the time these rules can be quite large, maximizing BIND/copy overhead, so you definitely don't want to put the extensive ones in a FOREACH or a closure. Switching to definitional break would have three real downsides: * Every loop would need to BIND/copy, every time the loop is called, including the loops that we were explicitly using because they *don't* BIND/copy. * Code that is not nested in the main loop block would not be able to break from that loop. And code that is nested in the main loop would BIND/copy. * We can in theory catch unwinds, run some recovery code, and send them on their way (hopefully only in native code, see #1521). Definitional escapes might be hard or impossible to catch in this way, depending on how they are implemented, and that would mean that you couldn't recover from breaks anymore. The upside to definitional break would be that you could skip past a loop or two if you wanted to, something you currently can't do. Another way to accomplish that would be to add /name options to all the loop functions, and that wouldn't have the BIND/copy overhead. Or to use THROW or THROW/name. The situation with THROW is similar to that of the non-binding loops, but more so, still task-safe because of functions. But CATCH and THROW are typically the most useful in two scenarios: * Escaping through a lot of levels that would catch dynamic breaks or returns. * Premade custom escape functions that might need to enforce specific semantics. Both of these uses can cause a great deal of difficulty if we switched to definitional throw. In the first case, the code is often either broken into different functions (and thus not nested), or all dumped into a very large set of nested code that we wouldn't want to BIND/copy. Remember, the more levels we want to throw past, the more code that goes into implementing those levels. In the second case definitional throw would usually not work at all because the CATCH and the THROW would contained in different functions, and the code that calls the function wrapping the THROW would not be nested inside the CATCH. So you would either need to rebind every bit of code that called the THROW, or the definitional THROW would need to be passed to the code that wants to call it like a continuation (similar concept). Either way would be really awkward. On the plus side of dynamic (whatever), at least it's easy to catch an unwind for debugging, testing or recovery purposes. For that matter, the main advantage of using THROW/name as the basic operation that developers can use to make custom dynamic escape functions is that we can build in a standard way to catch it and that will work for every custom escape that is built with it. The end to the arms race of break-through and catch. | |
BrianH: 11-Nov-2010 | Definitional (whatever) depends on a BIND to do its work, deep, usually BIND/copy. And that only works on words that are physically in the blocks that you bind, or in blocks that are nested in those blocks, etc. Another block that is outside the block you are binding and referred to by name won't be bound. That is the limit of the definitional approach. | |
BrianH: 12-Nov-2010 | Yes, but lexical scope has nothing to do with lexical keywords. | |
Ladislav: 12-Nov-2010 | I do understand that "blocks don't have to be nested", but that does not relate to the fact, that break in parse behaves lexically | |
Ladislav: 12-Nov-2010 | {very novice question - parse [break] is not the same as parse [(break)] internally?} - correct, they are two completely unrelated constructs, the latter being "foreing" to parse, related to the do dialect, in fact | |
Ladislav: 12-Nov-2010 | ... I know that Ladislav's DO-ALL is a loop, and so not wanting BREAK to apply to it is more of an opinion than something inherent in its nature. - I was afraid, that the DO-ALL was not a fortunate choice! My original problem with the property illustrated by DO-ALL occurred when I Implemented my PIF (now called CASE for the newcomers), which was not meant to catch any breaks, as is immediately obvious. | |
BrianH: 12-Nov-2010 | Debug/test needs a standard way to catch everything, but afaict there is no way to do so with definitional return. The same would go for the others if they were definitional, but that is less likely for the reasons given above. We might just have to live with not being able to catch definitional return - it should be easy to control the test environment so its return functions don't propagate into the test code, so that probably won't be a problem, at least for returns. | |
BrianH: 12-Nov-2010 | Yup. But I was mostly referring to the standard way the loop functions are used. Most loops are mostly made up of nested blocks and such, with very little direct DO calls to other blocks by name. | |
BrianH: 12-Nov-2010 | DO (or IF, or ALL, ...) of a block by name tends to only show up in advanced code. That code tends to be critical, and we usually can't afford to make it non-working, but not many people do that level of hand-optimization of their code, mostly because their code isn't that speed or size critical, or they don't know how (or they don't like that technique). On the other hand, PARSE rules called from loops are often referred to by name and are moved physically outside of the loops that call them for really good reasons, some of which I mentioned above. | |
BrianH: 12-Nov-2010 | Carl uses the manual CSE trick a lot - I learned to do so from him :) | |
BrianH: 12-Nov-2010 | You don't lose anything that you haven't already lost for other reasons, and it is possible (in native code) to build in acceptable workarounds for its weaknesses, so there's no significant downside to definitional return (except the work Carl would have to do to implement it). | |
Ladislav: 12-Nov-2010 | In the case of BREAK (I mean the one used in the DO dialect now), the situation is 50:50, since loops would be bound once, done many times anyway, making any slow-down % much smaller, and due to the fact, that some loops (as you mentioned earlier too), need to bind their bodies anyway | |
BrianH: 12-Nov-2010 | I don't know how much R3 code you've had to optimize, but I've had to optimize it a lot. That BIND/copy overhead is significant. It takes a *lot* of loop reps to balance it out, more than most code needs to do by something like an order of magnitude. It's not 50:50. | |
BrianH: 12-Nov-2010 | Carl has mused that there might be a faster way to do BIND/copy in loops. It would be welcomed. | |
Ladislav: 12-Nov-2010 | Well, I do not hesitate to use Foreach or Repeat where appropriate | |
Ladislav: 13-Nov-2010 | To make myself clear, I do not object against the word 'self being protected..., the only thing I mind about is the "keywordness" of the word. | |
BrianH: 13-Nov-2010 | Really awkward to do so though, and you can't just see the structure in source so it is harder for many people to understand. | |
BrianH: 13-Nov-2010 | We could really use a native LET or SELFLESS - either would do, actually, and could be used to implement the other. | |
Henrik: 14-Nov-2010 | Well, I think it would be clearer to see it applied in loops and using multiple values. As it is shown there, USE and DO FUNC are clearer to me. It may be very useful. | |
Ladislav: 14-Nov-2010 | As far as the DO FUNC examples go, they are just equivalent to the LET examples, as is quite obvious. The distinctions are rather small, like the fact, that you do not need to create a function and then call DO | |
Ladislav: 14-Nov-2010 | less overhead for the user (does not have to call DO), less overhead for the interpreter (does not have to create the function), and a couple more quirks like RETURN and EXIT handling | |
Maxim: 15-Nov-2010 | on the question, why do we really need self: self is very usefull when you use objects within code, because there can often be binding clashes. self assures one that a parameter is always from the context and not from the function. self.x: x has occured pretty often for me. its also very usefull when you need to return the context from which a function was bound. I also use it to do indirection: obj: self context [ parent: obj ] remove self, and we can't say that REBOL has objects anymore. many things will become really complicated for no reason. | |
Andreas: 25-Nov-2010 | A more direct way to cause a basic error might be very useful. Currently, if you don't want/need to give any thought what an appropriate error might be you'll do: cause-error 'user 'message "error message" Which is a lot longer than `make error! "error message"` was in R2. Having written the above in R3 a lot, recently, I now use a CAUSE-USER-ERROR shorthand, which might be nice to have in general: cause-user-error "error message" | |
BrianH: 25-Nov-2010 | You can still do this in R3: do make error! "error message" The only difference from R2 is that you have to DO the error to trigger it. |
10101 / 11578 | 1 | 2 | 3 | 4 | 5 | ... | 100 | 101 | [102] | 103 | 104 | ... | 112 | 113 | 114 | 115 | 116 |