• Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

AltME groups: search

Help · search scripts · search articles · search mailing list

results summary

worldhits
r4wp64
r3wp928
total:992

results window for this page: [start: 1 end: 100]

world-name: r4wp

Group: #Red ... Red language group [web-public]
Pekr:
5-Mar-2012
Because if you are aiming for more complete solution, why not to 
bind to Qt for e.g. ? Seems to be used by many ...
Kaj:
4-Jun-2012
I think the FastCGI server is doable now. Instead of writing a complete 
one, you could probably also find a library written in C and bind 
to it
Kaj:
5-Aug-2012
Will there be something like USE or BIND to compile code referencing 
a particular context?
Kaj:
11-Aug-2012
I was disappointed when that was rejected. I have a VM where I need 
to bind to dynamic stacks of contexts
Steeve:
11-Aug-2012
I used several BIND in sequences. Not neat
Steeve:
11-Aug-2012
is: func [
		[catch]
		{Current face inherits from a block!}
		spec [block!]
		/local locals old when init
	][
		either all [
			find spec set-word!	; locals founds
			not empty? exclude  ; new ones (not found in the current face)

    first locals: construct copy spec ; copy: because [construct] modifies 
    the block (R2 bug ?)
				first face
		][

   ; Would be simpler, faster and safer using R3 (objects can be expanded)
			; rebuild face with new locals 

   ; (make face spec : can't be used here because of the special bounding 
   rules)

   when: face/when					; prevent copy/deep of when and init blocks
			init: face/init
			face/when: face/init: none
			set locals none

   resolve* locals face			; initialize locals with current face (if 
   intersect)

   face: make old: face locals		; rebuild current face with new locals
			face/when: when
			face/init: init
			do-safe bind bind spec face self; run style constructor 

   bind bind init face self		; rebound current face constructor (which 
   is currently running)

   error? set old :bound-err		; prevent old object from being used anymore
			old: none
		][
			; no new locals

   do-safe bind bind spec face self		; just run style's constructor 
		]
		if error throw-exit
	]
Kaj:
11-Aug-2012
Maybe it was about BIND directly
Pekr:
25-Aug-2012
What I still think is, that we need strong parse. It is very cool 
technology. Yes, I dare to call it a technology. We need r3 level 
parse. Then we can create dialects, and show other guys, that dialecting 
is a cool concept. Pity we were not able to capitalise on it more, 
mainly due to closed nature of R2 possibilities to bind to other 
environments .... you imo :-)
DocKimbel:
20-Oct-2012
Lexical binding will be added when we'll add contexts (in a few weeks), 
along with dynamic binding (yes, you'll be able to have fun with 
BIND again ;-)).
Kaj:
30-Nov-2012
That's no problem if I bind the canvas widget, but I'd rather do 
it in Enlightenment
Kaj:
7-Jan-2013
Other than that, many of the libraries that I bind are not or not 
easily available on Android, so functionality is currently more limited
Pekr:
15-Feb-2013
What would be also cool would be to bind to one of media frameworks 
- libVLC, ffmpeg, Libav, mplayer, Gstreamer, etc. - dunno which one 
is the best ....
Kaj:
1-Mar-2013
Any framework that supports more than one image format will have 
its own internal format. That goes for R2, SDL, GDK, ImageMagick 
and any other framework you could bind to
Kaj:
1-Mar-2013
If you bind to LibJPEG directly, you'll have to devise your own internal 
format once you add support for another image type
DocKimbel:
25-Mar-2013
You need to created a new context on each REPEAT call (or use some 
hacked way of caching it) and you need to BIND the loop body (even 
probably BIND/COPY it to be cleaner). Now think about the costs of 
nested loops...and all that because you don't want to define another 
local word, that could anyway be added for you by FUNCTION. Think 
twice about the trade-offs.
DocKimbel:
25-Mar-2013
>> foo: func [code [block!]][repeat i 1000 code]
>> foo [i]
== 1000

So both R2/R3 do re-bind the body block on each call.
DocKimbel:
25-Mar-2013
Red would raise an error ("word has no value!") running the same 
code in the interpreter. You would need to write it this way to make 
it work:


    foo: func [code [block!] /local i][repeat i 1000 bind code 'i]


That makes the required BIND operation explicit, so the same flexibility 
as in Rebol could be achieved but in a user-controlled way and only 
when needed.
Gregg:
29-Mar-2013
BTW, Doc, since you did BIND yesterday, I added COLLECT. Need to 
test more, but it works!
Kaj:
3-Jul-2013
1058 is driver deactivated or couldn't bind to any devices
Kaj:
19-Jul-2013
Normally, you would bind low level interfaces or code using Red/System, 
or the DLL interface in R3, or an extension in R3. You would then 
marshall all the arguments of the low level functions back and forth 
to Red or REBOL all the time
Group: Ann-Reply ... Reply to Announce group [web-public]
BrianH:
25-Sep-2012
OS libraries and R3 libraries are both libraries. However, with GPL2 
they make an exception for linking to OS libraries even if they're 
closed source. With GPL3 they extended that exception to libraries 
that come with a runtime or VM, like Java, .NET, or closed-source 
REBOL. The exception doesn't go the other way though: It's not allowed 
to link to GPL'd libraries with closed code.


Ladislav, the runtime library is used to implement the interpreters, 
and includes the interpreters for that matter, but it's still a library. 
The DO interpreter really doesn't do a lot; it resolves the op and 
path syntax and dereferences words, but everything else is done by 
the functions of the runtime library, which your code is bound to 
at runtime. But for the good news, it's at runtime, so afaict the 
GPL doesn't require you to release your source because of that binding, 
as long as you load the source at runtime, which you pretty much 
have to do at the moment for scripts.


Encapping is a trick, but you can handle that with some limitations. 
Extensions will need to be GPL 2, and that means that they can't 
be used to wrap closed-source libraries unless they were included 
with the operating system you're running on. Encapping regular scripts 
and modules is semantically iffy, but you could handle that with 
a FAQ entry that explicitly says that loading a R3 script doesn't 
count as linking, even if you bind the words to GPL'd values. The 
same FAQ entry would apply to scripts in files, databases, whatever.
Group: Rebol School ... REBOL School [web-public]
Sujoy:
21-Apr-2012
have an issue:
>> fact1: 'a/a
>> num1: 99.0
>> blk: [greater? to-decimal obj/:fact1 num1]
>> objs: []
>> o: make object! [a: make object! [a: "100.0"]
>> append objs o
>> o: make object! [a: make object! [a: "99.0"]
>> append objs o

>> foreach obj objs [if equal?  do bind blk 'obj true [print obj/a]]
**Invalid path value: a/a
Steeve:
21-Apr-2012
>> blk: [greater? to-decimal do bind reduce [fact1] obj num1]
Sujoy:
21-Apr-2012
>> foreach obj objs [print do bind blk 'obj]
** Script Error: Invalid path value: a
** Near: a/a
Steeve:
21-Apr-2012
I repeat, did you take that correction ?
>> blk: [greater? to-decimal do bind reduce [fact1] obj num1]
Steeve:
21-Apr-2012
copy that, it must work:

fact1: 'a/a
num1: 99.0
blk: [greater? to-decimal do bind reduce [fact1] obj num1]
objs: []
o: make object! [a: make object! [a: "100.0"]]
append objs o
o: make object! [a: make object! [a: "99.0"]]
append objs o
foreach obj objs [if equal?  do bind blk 'obj true [print obj/a]]
Sujoy:
21-Apr-2012
if i do:

fact1: 'a
o: make object [a: "100.9"]
append objs o
foreach obj objs [if equal?  do bind blk 'obj true [print obj/a]]
** Script Error: Invalid argument: a: "100.0"
Sujoy:
21-Apr-2012
a


blk: any [greater? to-decimal probe do bind reduce [fact1] obj num1 
| greater? to-decimal do bind obj/:fact1 obj num1]??
Steeve:
21-Apr-2012
fact1: 'a
get-prop: func [o][either object? o [first next second o][o]]

blk: [greater? to-decimal get-prop do bind reduce [fact1] obj num1]objs: 
[]
Gregg:
22-Apr-2012
You're ramping up fast sujoy. Most people don't get to using BIND 
for a long time. :-)
Sunanda:
28-Apr-2012
REBOL is structured more like LISP or Haskell (but without being 
a pure functional language).


So, yes, it does not have direct access to the machine instructions 
or low-level op sys APIs in the way that assembler or assembler-wrapper 
languages (like C) does.


What REBOL does have is easy integrated access to very high level 
APIs: parse. bind, map, etc.
BrianH:
31-Jul-2012
Nonetheless, FORSKIP has less overhead than FOR, even on R2. Simpler 
mezz code, no BIND/copy overhead.
BrianH:
27-Aug-2012
IIRC in R3 closures do a BIND/copy of their bodies at every call, 
then execute the copy. As soon as the USE is finished executing its 
context and body are no longer referenced, at least if you didn't 
save a reference elsewhere. The context containing the 'f and the 
function it references would be able to be GC'd as soon as the USE 
returns.
BrianH:
27-Aug-2012
Yeah, R3's USE does a COPY/deep of the body, then make closure! uses 
the copy itself, then when executed (IIRC) the closure executes a 
BIND/copy of its body. So it copies its body more than once, but 
possibly less than twice.
BrianH:
27-Aug-2012
Whoah, it turns out that R3's closures do more than a regular BIND/copy 
when they run, they copy strings too. Surprised I hadn't tried that.
>> c: make closure! [[] [append "" 1]]
>> c
== "1"
>> mold :c
== {make closure! [[][append "" 1]]}
BrianH:
27-Aug-2012
Same in R2: MAKE function! does more than a BIND/copy on its body 
as well, it also copies strings.
>> c: closure [] [append "" 1]
>> source c
c: func [][native action function! [[throw]] [append "" 1]]
>> c
== "1"
>> c
== "1"
>> source c
c: func [][native action function! [[throw]] [append "" 1]]
Maxim:
27-Aug-2012
I always  though  BIND/copy    was   equivalent to    BIND COPY/deep
BrianH:
27-Aug-2012
BIND/copy doesn't copy everything, it just copies everything that's 
bindable. So, no copying of strings, objects, functions, modules, 
lists or hashes, but it copies blocks, parens and paths. Words are 
of course copied because they're literal values.
BrianH:
27-Aug-2012
Functions and objects aren't copied, but everything else seems to 
be:


>> a: reduce ["" #{} 'a/b [] quote () make list! [] make hash! [] 
does [] context []]

== ["" #{} a/b [] () make list! [] make hash! [] func [][] make object! 
[
    ]]
>> b: bind/copy a 'a

== ["" #{} a/b [] () make list! [] make hash! [] func [][] make object! 
[
    ]]
>> map-each [x: y] b [same? :y first at a index? x]
== [false false false false false false false true true]
BrianH:
27-Aug-2012
I guess that R2's make function! and R3's closures to a BIND/copy 
after all.
Endo:
28-Aug-2012
Why this doesn't work?
e: func [] [f]

context [f: does [print "ok"] do bind 'e self] ;error: f has no value

or when I BIND the F inside E, still doesn't work:
o: context [f: does [print "ok"]]
bind first second :e o
e
** Script Error: f has no value

while this one works:
do bind first second :e o
== ok

doesn't F stay BINDed?
DocKimbel:
28-Aug-2012
In your first try (bind 'e self), you're binding only this 'e word, 
not the :e function body, so if you replace it with: bind second 
:e self, it will work.


In second try, you're never binding 'e function body, you've just 
binded a new instance of 'f word that you have created using FIRST. 
That's why it works when you add DO, you're evaluating that new 'f 
instance which has the correct binding. Just remove FIRST, it will 
bind 'e body block and you'll get the result you've expected.

>> e: func [] [f]
>> o: context [f: does [print "ok"]]
>> bind second :e o
== [f]
>> e
ok
Endo:
28-Aug-2012
Got it, thanks a lot. I didn't know that FIRST gives me a "new" word, 
I thought that I'm BINDing *the* word itself and it should stay BINDed.

This confused me a bit:
>> o: context [a: 1 b: 2 c: 3]

>> foreach x bind [a b c] o [probe get x] ;this works, BINDs block 
to O

>> foreach x [a b c] [probe get bind x o] ;this works too, BINDs 
the word 'X to O
DocKimbel:
28-Aug-2012
No, it doesn't bind 'x, it binds x, which is evaluated to 'a, 'b 
or 'c.
DocKimbel:
28-Aug-2012
If you write in the loop: bind 'x o, it will fail, because 'x is 
not defined in o.
Endo:
28-Aug-2012
I see, thank you. And in the first line, it doesn't BIND *the block* 
to O, it BINDs the block of words (which are 'a, 'b and 'c) to O. 
It's clear now. Thanks!
MarcS:
3-Oct-2012
(for the BIND)
Ladislav:
3-Oct-2012
OK, this is the long version:

tail-func: func [
    {

  Define a recursive user function with the supplied SPEC and BODY.
     	The function can use a special TAIL-CALL local function
     	to perform a tail-recursive function call.
    }
    [catch]


 spec [block!] {Help string (opt) followed by arg words (and opt type 
 and string)}
    body [block!] {The body block of the function}
    /local the-function tail-call context-word
] [
	; define a new 'tail-call local variable
	tail-call: use [tail-call] ['tail-call]
	
	; bind the given BODY to "know" the 'tail-call variable
	body: bind/copy body tail-call
	
	; find a local word in SPEC
	context-word: find spec word!
	if context-word [context-word: first context-word]
	
	; define the TAIL-CALL function
	set tail-call func spec compose [
		(
			either context-word [
				; set parameters to the new arguments
				compose [set parameters values? (context-word)]
			] [[]]
		)
		throw/name none 'tail-call
	]
	
	; define the function
	the-function: throw-on-error [
		func spec compose/deep [
			(either context-word [context-word] [[]])
			while [true] [
				catch/name [
					return do [(body)]
				] 'tail-call
			]
		]
	]
	
	if context-word [
		; get the function context
		context-word: bind? first second :the-function
		
		; replace the context word in the function body by NONE
		change second :the-function none

		; adjust the TAIL-CALL body
		; replace the 'parameters word

  change/only at second get tail-call 2 bind first context-word context-word
	]

    :the-function
]

values?: func ['word] [second bind? word]
Steeve:
4-Oct-2012
Completly changed my mind. It's lot leasier to manage /recur as a 
refinement! 
- eg. safe/recur instead of recur

- no words collision anymore (obviously /recur can't be used as a 
parameter).
Also really short code 

rfunc: func [[catch] spec [block!] body [block!] /local ctx fun][
    spec: append copy spec /recur

    ctx: bind? first second fun: throw-on-error [func spec [recur]]
    change second :fun compose/deep [
        if (in ctx 'recur) [throw/name second (ctx) 'recur]
        while [true][

            set/any [(bind to-block form first ctx ctx)] catch/name [
                return do [(bind/copy body ctx)]
            ] 'recur
        ]
    ]
    :fun
]
Steeve:
5-Oct-2012
;Go back to recur as a function.
;Still recur can't be used as a parameter, local or a refinement.

;This implementation is much more clean (no shitty compose/deep) 
and still very short.

;The collision of words is avoided by the use of singleton functions 
#[function!]
;I'm confident with this one. It could be the last one -_-;


rfunc: func [[catch] spec [block!] body [block!] /local ctx args][
    ctx: bind? first second throw-on-error [
        ;* Temporary function created to retrieve parameters
        ;* and to get a new context for 'recur.
        ;* The context will remain alive (not GC'ed).
        func append copy spec /recur [recur]
    ]
    args: bind to-block form first ctx ctx
    ctx/recur: func spec reduce [

        quote #[function! ['word] [throw/name second bind? word 'recur]] 

        first args ;* may be 'recur if empty specs (still, it's ok)
    ]
    func spec reduce [
        quote #[function! [args body][

            while [true][set/any args catch/name [return do body] 'recur]
        ]] 
        head remove back tail args ;* remove 'recur
        bind/copy body ctx         ;* bound 'recur
    ]
]
Steeve:
5-Oct-2012
;Go back to recur as a function.
;Still recur can't be used as a parameter, local or a refinement.

;This implementation is much more clean (no shitty compose/deep) 
and still very short.

;The collision of words is avoided by the use of singleton functions 
#[function!]
;I'm confident with this one. It could be the last one -_-;


rfunc: func [[catch] spec [block!] body [block!] /local ctx args][
    ctx: bind? first second throw-on-error [
        ;* Temporary function created to retrieve parameters
        ;* and to get a new context for 'recur.
        ;* The context will remain alive (not GC'ed).
        func append copy spec /recur [recur]
    ]
    args: bind to-block form first ctx ctx
    ctx/recur: func spec reduce [

        quote #[function! ['word] [throw/name second bind? word 'recur]] 

        first args ;* may be 'recur if empty specs (still, it's ok)
    ]
    func spec reduce [
        quote #[function! [args body][

            while [true][set/any args catch/name [return do body] 'recur]
        ]] 
        head remove back tail args ;* remove 'recur
        bind/copy body ctx         ;* bound 'recur
    ]
]
BrianH:
5-Oct-2012
I haven't examined the code enough to determine if this would help, 
but one trick to avoid having to reserve a word to refer to your 
recursion function is to use an inline reference to the function 
value instead. That is a trick that has been used in some mezzanine 
functions, though I don't know if they're still in REBOL. Inline 
references to function values are not rebound when you bind the code 
block that references them.
BrianH:
5-Oct-2012
Functions specified with serialized syntax don't bind their words 
in R3, so you might want to use Ladislav's suggestion.
Ladislav:
5-Oct-2012
rfunc: func [[catch] spec [block!] body [block!] /local ctx fun][
    spec: append copy spec /recur

    ctx: bind? first second fun: throw-on-error [func spec [recur]]
    change second :fun compose/deep [
        if (in ctx 'recur) [throw' second (ctx)]
        while [true][
            set/any [(bind to-block form first ctx ctx)] catch' [
                return do [(bind/copy body ctx)]
            ]
        ]
    ]
    :fun
]
Steeve:
5-Oct-2012
; Sorry Ladislav I've stolen your idea one should avoid catch/throw 
interferences

; As an extra (also your idea ?), f/recur and recur are now both 
allowed.

rfunc: func [[catch] spec [block!] body [block!] /local ctx fun][
    ctx: bind? take second fun: throw-on-error [
        func append copy spec /recur reduce ['recur body]
    ]
    insert second :fun reduce [

        quote #[function! [[throw] ctx args 'fun body /local ret][

            if :ctx/recur [ctx/recur: ctx throw/name second ctx 'recur]
            ctx/recur: :fun
            while [true][
                set/any 'ret catch/name [return do body] 'recur

                unless all [value? 'ret block? :ret same? ctx last ret][
                    throw/name get/any 'ret 'recur
                ]
                set/any args ret
            ]
        ]]

        ctx (bind head remove back tail to-block form first ctx ctx) :fun
    ]
    :fun
]
Steeve:
5-Oct-2012
; Ladislav I can't see if you posted new code (WTF Altme)

; So I've tried your idea one should avoid catch/throw interferences

; As an extra (also your idea ?), f/recur and recur are now both 
allowed.

rfunc: func [[catch] spec [block!] body [block!] /local ctx fun][
    ctx: bind? take second fun: throw-on-error [
        func append copy spec /recur reduce ['recur body]
    ]
    insert second :fun reduce [

        quote #[function! [[throw] ctx args 'fun body /local ret][

            if :ctx/recur [ctx/recur: ctx throw/name second ctx 'recur]
            ctx/recur: :fun
            while [true][
                set/any 'ret catch/name [return do body] 'recur

                unless all [value? 'ret block? :ret same? ctx last ret][
                    throw/name get/any 'ret 'recur
                ]
                set/any args ret
            ]
        ]]

        ctx (bind head remove back tail to-block form first ctx ctx) :fun
    ]
    :fun
]
Steeve:
5-Oct-2012
; Ladislav I can't see if you posted new code (WTF Altme)

; So I've tried your idea one should avoid catch/throw interferences

; As an extra (also your idea ?), f/recur and recur are now both 
allowed.

rfunc: func [[catch] spec [block!] body [block!] /local ctx fun][
    ctx: bind? take second fun: throw-on-error [
        func append copy spec /recur reduce ['recur body]
    ]
    insert second :fun reduce [

        quote #[function! [[throw] ctx args 'fun body /local ret][

            if :ctx/recur [ctx/recur: ctx throw/name second ctx 'recur]
            ctx/recur: :fun
            while [true][
                set/any 'ret catch/name [return do body] 'recur

                unless all [value? 'ret block? :ret same? ctx last ret][
                    throw/name get/any 'ret 'recur
                ]
                set/any args ret
            ]
        ]]

        ctx (bind head remove back tail to-block form first ctx ctx) :fun
    ]
    :fun
]
Steeve:
5-Oct-2012
This time it's really really my final version T_T
- Both f/recur and recur allowed
- Catch/throw interferences ok.

NB: The code would be simpler in R3 since several workarounds are 
used to correct misbehaviors of object related natives of R2.

Also the lack of the reflexive capability for a function to read 
its own context in a easy way is definitivly a huge miss.

(On can't create anonymous functions without analysing their specs 
first. What a pain)

One would need a reserved word holding the context (like SELF for 
objects).

These shortcomings are making the code too much obfuscated and huge 
for my taste.
I hope it will be corrected in R3..

rfunc: func [
    [catch] spec [block!] body [block!] 
    /local ctx args call-tail
][
    ctx: bind? first second throw-on-error [
        func spec: append copy spec /recur [recur]
    ]
    args: bind head remove back tail to-block form first ctx ctx
    call-tail: func ['word] compose/deep [
        set/any [(args)] second bind? word 
        throw/name (ctx) 'recur
    ]
    ctx/recur: func spec reduce [:call-tail 'recur]
    func spec reduce [
        quote #[function! [
            [throw] 'recur 'call-tail ctx args body /local ret
        ][
            if get/any recur [call-tail :recur]
            set recur get in ctx 'recur
            while [true][
                set/any 'ret catch/name [return do body] 'recur
                unless all [value? 'ret same? :ret ctx][
                    throw/name get/any 'ret 'recur
                ]
                set/any args second ctx
            ]
        ]]
        'recur :call-tail ctx args body
    ]
]
BrianH:
11-Mar-2013
For R2: native loops are faster than mezzanine (function) loops, 
so much faster that their individual differences amongst themselves 
are almost irrelevant. For R3 all loops are native (except FIND-ALL, 
temporarily), so the big difference is one-time-per-call bind/copy 
overhead for binding loops, versus not having that for non-binding 
loops.
BrianH:
11-Mar-2013
For R2 I would use LOOP, REPEAT, FOREACH or WHILE whenever possible. 
In R3, REPEAT and FOREACH have bind/copy overhead, while FORALL and 
FORSKIP don't, so the latter can be faster in many cases. WHILE and 
LOOP are the same in R3 as they were in R2, at least relative to 
the other native loops.
BrianH:
11-Mar-2013
FOR has bind/copy overhead in R3 and is a complex mezzanine in R2, 
so I only use it when it is really appropriate.
Group: Databases ... group to discuss various database issues and drivers [web-public]
BrianH:
22-Mar-2012
Here is the code I use to load your ODBC extension, which patches 
it after load:

; Load and patch the ODBC extension
odbc: import/no-user %odbc.dll
unless 'case = pick body-of :system/schemes/odbc/actor/open 10 [

system/schemes/odbc/actor/open: func [port [port!] /local result] 
bind [
	port/state: context [access: 'write commit: 'auto] 

 result: open-connection port/locals: make database-prototype [] case 
 [
		string? select port/spec 'host [ajoin ["dsn=" port/spec/host]]
		string? select port/spec 'target [port/spec/target]
		'else [cause-error 'access 'invalid-spec port/spec]
	]

 all [block? result lit-word? first result apply :cause-error result] 
	port
] odbc
]
Group: !REBOL3 ... General discussion about REBOL 3 [web-public]
Maxim:
21-Jan-2013
one big difference is that slim doesn't bind to a global library 
area.   each module is completely shielded and imports "on its own". 
 

its a hierarchical system without namespaces.
AdrianS:
11-Feb-2013
has much changed wrt bind for Rebol 3? I see, for example that this 
line (under 'Variables') in the Bindology section on rebol.net returns 
true whereas it used to return false with R2. Is that article 

variable? /rebol

Just a bit lower this:

o: make object! [a: none]
o-context: bind? in o 'a
same? o o-context ; == false -> now returns true

Is there an R3 specific explanation of binding?

world-name: r3wp

Group: Core ... Discuss core issues [web-public]
Brett:
2-Mar-2005
; Jaime try comparing your example with this:
o: context [a: 0 b: o1: none]
o/o1: context bind [a: 1 c: 3 set 'b 2 o2: none] in o 'a

o/o1/o2: context bind (bind [set 'b 4 set 'c 5 set 'd 6] in o 'a) 
in o/o1 'a
; I think you'll find they are equivalent.
Brett:
2-Mar-2005
I don't think there is a hierarchy of contexts.

In Jaime's example there is a hierarchy of blocks (nested). As evaluation 
proceeds, the words in those blocks get "painted" different colours. 
That's why my code using bind ends up with the same binding of words 
even though I didn't have the same hierarchy of blocks  - I simulated 
the same order of binding.
Volker:
2-Mar-2005
'a is first bound to 'global, then to 'red, then to 'blue (going 
from outer to inner block). then it stays blue until you bind it 
again.
Group: I'm new ... Ask any question, and a helpful person will try to answer. [web-public]
DideC:
10-Mar-2005
ctx: context bind [
	chars: charset [ #"A" - #"Z" #"a" - #"z" #"0" - #"9" #"-" #"_"]
	non-chars: complement chars

	set 'copy-word has [start end end-rule car-pos] [
		if any [not focal-face not caret] [exit]
		
		car-pos: index? caret
		end-rule: copy []
		
		parse/all head caret [
			any [
			 	start: some chars end: (

     if all [car-pos >= index? start car-pos <= index? end] [end-rule: 
     'break]
				) end-rule
				| some non-chars (start: end: none)
			]
		]

  if all [start end] [write clipboard:// probe copy/part start end]
	]
] in system/view 'focal-face

view layout [
	area "This is some text to test"

 text "To copy the word under the cursor : hit CTRL+K or press the 
 button bellow"
	button "Copy word" #"^K" [copy-word]
]
Anton:
10-Mar-2005
There's a nice example of BIND. The whole block of words is first 
BINDed to the system/view object. Only the words that already exist 
in system/view (like 'copy-word) will be rebinded, (because objects 
cannot be extended with new words).
Anton:
10-Mar-2005
So it's a double-bind :-)
Luisc:
10-Mar-2005
I have been looking at scripts Anton on Bind ( found over 40 at rebol) 
. This is great !!! 8D
Luisc:
10-Mar-2005
donno but it does what i need  =)  and it looks "easy" hmmm I can 
see why someone can get addicted to rebol. I need to study more about 
bind and parse.
Normand:
12-Apr-2005
Speaking of double bind, I have no clue of the how-to to this clue. 
 In Ocaml we can make co-recursive definitions, also with negation. 
 But when I try this on Rebol, it claims the value before I have 
the time to define it:  a: not b and b: not a.   Interp: ** script 
error, b has no value.  What is the method ?  Or are we out of paradise? 
 I could use that as a form of loop, or a form of lexical closure 
to model some linguistic phenomenas.  But how?  We know the problems 
of complement of complement, but as a function value it should be 
feasible.
Group: !RebGUI ... A lightweight alternative to VID [web-public]
Brock:
30-Apr-2005
I like it so far - haven't looked at the code or how you bind the 
data.
Group: !Uniserve ... Creating Uniserve processes [web-public]
Terry:
4-Feb-2006
And if I LOAD the external file, you would think it would bind it 
all globally, but it doesn't?
Terry:
4-Feb-2006
Seems it relates to this part (from the docs)  

Put all the service related code in the service definition. You can 
include external libraries of code if needed. Everything that's not 
inside the service definition block will be globally BIND-ed.
Group: Rebol School ... Rebol School [web-public]
JaimeVargas:
4-Apr-2006
MY-WORD: (notice the colon) is the what is used to bind a word (kind 
of a C assignment)
BrianH:
5-Apr-2006
The other main thing that will likely trip you up is understanding 
how words, contexts and bind, together serve the role that variables 
or symbols serve in other languages. I could go on about that, but 
you would be better served by reading the extensive articles that 
Ladislav, Gabriele and I have already written on the subject.
denismx:
8-Apr-2006
Words, contexts and bind... : Ladislav, Gabriele and BrianH articles. 
I suppose I will find those articles on rebol.org? I will look them 
up and read them. And the presentations on Dialects... although what 
I understood about that was that one could make up dialects for a 
particular use. If so, not sure it would help in the ingeneering 
of a "better" teaching/learning approach for the language.
JaimeVargas:
9-Apr-2006
Symbols can only bind to values. The pointer metaphor is just easy 
way to expaning things but it is not correct.
BrianH:
10-Apr-2006
And when you bind a, you make it point to another context with another 
slot in it.
BrianH:
11-Apr-2006
A word is basically a value that can be put in a value slot. This 
value includes a pointer to a symbol and a pointer to a context.


A symbol is like a string that is only stored once. The symbol that 
is pointed to by a word is the same symbol (same chunk of data) as 
that pointed to every other word that is made up of the same characters 
as the word (case-insensitively).


A context is like a map from symbols to value slots. When you create 
a context it has the specified set of symbols associated with it 
and each one of these symbols has an associated value slot. When 
you bind a word to a context, you change the context pointer of a 
word to point to the context. If you try to bind a word to a context 
that doesn't include the word's symbol, the bind fails silently and 
the word is unchanged. With the exception of system/words, all contexts 
are of fixed length once they are created (for now).


If the word's context pointer is not set, the word is considered 
unbound. If the corresponding value slot in the context the word 
is bound to is supposedly empty, the value slot really contains the 
unset! value, and the word is considered unset.


(Current implementation) Every word you create is added to the system/words 
context, which expands to include it if it isn't already there. Currently, 
system/words has an upper limit of 8000 words. This effectively means 
that the words your script uses must not exceed 8000 unique symbols, 
including those used by the runtime.
Anton:
22-Apr-2006
Ok, so here's my frequency table:
    6 compose 
    5 as-pair 
    5 func 
    4 do 
    3 show 
    2 all 
    2 copy 
    2 find 
    2 form 
    2 get 
    2 in 
    2 pick 
    2 print 
    2 to-image 
    2 use 
    1 * 
    1 + 
    1 - 
    1 <> 
    1 = 
    1 append 
    1 bind 
    1 center-face 
    1 change 
    1 clear 
    1 context 
    1 do-events 
    1 either 
    1 first 
    1 foreach 
    1 if 
    1 join 
    1 layout 
    1 load-thru 
    1 make 
    1 mold 
    1 object? 
    1 reduce 
    1 remold 
    1 remove-each 
    1 repeat 
    1 second 
    1 select 
    1 to-pair 
    1 to-path 
    1 view
Group: rebcode ... Rebcode discussion [web-public]
BrianH:
12-Oct-2005
I've been thinking about temporary variables generated by rewrite 
rules. I have a way to generate extremely unlikely variable names, 
but no way to bind them in the rebcode function after they've been 
added. Any ideas?
BrianH:
14-Oct-2005
(Thinking out loud) It occurs to me that computed branches would 
be a lot easier if you could reference the target values in your 
code, so that you have something to compute with. If the offsets 
were absolute you could just assign them to the label words (something 
that could be done in the first pass of the assembler rewrite of 
the branch statements). Relative offsets could be calculated pretty 
easily if you had something like a HERE opcode that would assign 
the current position to a variable that could be used soon afterwards 
to calculate the relative offset. For that matter, the HERE opcode 
could perform the assignment of the original label as well, and even 
be accomplished by a rewrite rule in the branch fixup pass of the 
assembler.


Here's my proposal for a HERE assembler directive. No native opcodes 
would need to be added - this would be another directive like label. 
This directive could be used to set the target values to words for 
later computation. Assuming BRAW stays relative and no absolute computed 
branch is added, it could also be used in computations to convert 
from absolute to relative offsets. This would be sufficient to make 
computed branches practical.


- A new directive HERE, taking two arguments, a word and a literal 
integer.

It would set the word to the position of the HERE directive, plus 
an offset specified in the second parameter. The offset would need 
to be a literal because the calculation would be performed ahead 
of time by the assembler - 0 would mean no offset. If you don't want 
to reset the position every time you branch to the word use an offset 
of 3. Resetting the word after every branch would allow its use as 
a temporary in absolute-to-relative calculations, but that would 
only be an advantage until the JIT or optimizer is implemented - 
the choice would be up to the developer. Having a mandatory second 
argument is necessary for reasons that will become clear later.


- The HERE directive would be rewritten away in the fix-bl function 
of the assembler like this:

REBOL []  ; So I could use SciTE to write this message

fix-bl: func [block /local labels here label] [
    labels: make block! 16
    block-action: :fix-bl
    if debug? [print "=== Fixing binding and labels... ==="]
    parse block [
        some [
            here:
            subblock-rule (here/1: bind here/1 words)
            |

            'label word! (here/1: bind here/1 words insert insert tail labels 
            here/2 index? here)
            |  ; Beginning of the added code
            'here word! integer! (

                here/1: bind 'set words  ; This is why HERE needs two arguments

                here/3: here/3 + index? here  ; Offset from position of this directive
                if (here/3 < 1) or (here/3 > 1 + length? block) [
                    error/with here "Offset out of bounds:"
                ]
            )  ; End of the added code
            |
            opcode-rule (here/1: bind here/1 words)
            |
            skip (error here)
        ]
    ]
    parse block [
        some [
            here:
            ['bra word! | 'brat word! | 'braf word!] (

                if not label: select labels here/2 [error/with here "Missing label:"]
                here/2: label - index? here
            )
            |
            opcode-rule
            |
            skip (error here)
        ]
    ]
]
BrianH:
14-Oct-2005
Why not do both? Change

    'label word! (here/1: bind here/1 words insert insert tail labels 
    here/2 index? here)
to
    'label word! (
        here/1: bind here/1 words
        set here/2 index? here
        insert insert tail labels here/2 index? here
    )


No, since it wouldn't be set at runtime, it wouldn't be recursion-safe. 
The only safe way to do that would be to replace every reference 
to a label other than the label directive and the literal branches 
with  a constant value of its absolute offset, the one in the labels 
block. Doable, but awkward.
Group: RT Q&A ... [RT Q&A] Questions and Answers to REBOL Technologies [web-public]
BrianH:
3-Nov-2005
Kru, one of the list of suggestions we compiled for rebcode was a 
BIND opcode.
Volker:
11-Dec-2005
set w 'action
bind w object
getw value w
BrianH:
11-Dec-2005
As for the question about rebcode binding, let me make it clearer:


It would solve all of the object field retrieval problems in rebcode 
to have an opcode added that would be the equivalent to the IN native, 
or maybe BIND. You wouldn't need path evaluation to be added - you 
could just retrieve an object field word and use setw/getw with it. 
Yes, you can use apply, but it is very slow in comparison with opcodes. 
Working with object fields is a pretty basic operation that doesn't 
have any direct support in rebcode, and some have come to miss it, 
particularly those that use objects in data structures. I often use 
blocks for data structures when I can because of the context overhead 
of objects, but some are more used to thinking in object-oriented 
terms. Plus, there's all of those built-in object-based structures. 
Still, I suspect that many of these questions would go away if apply 
was faster :(
BrianH:
11-Dec-2005
Yes, this bind-like opcode was one of the requests that we came up 
with when we were compiling a list of rebcode enhancements. Thank 
you for implementing many of the other enhancements on that list 
:)
Gabriele:
11-Dec-2005
one solution is:

>> f: rebcode [] [add.i x x]
>> f': func [obj] [bind second :f obj f obj]
>> probe f' context [x: 3]
make object! [
    x: 6
]
BrianH:
11-Dec-2005
(Still to Volker for this) By using in rather than bind, you save 
a set instruction. Of course if the "object" word refers to a word 
rather than an object, that advantage is less so because we will 
have to convert the word to its context like this:
    apply w bind? [object]
    apply w in [object w]
    getw value w

But for that to work we would need a new rebcode alpha with the 2.6.2 
enhancements.
Gabriele:
11-Dec-2005
note that if speed is what you are after, this is likely to be the 
fastest way; if the object changes in a loop, then the rebcode advantage 
is probably not big, though i understand there may be cases in which 
a BIND or IN opcode would be desirable...
Group: SQLite ... C library embeddable DB [web-public].
Ashley:
14-Mar-2006
If someone has an SDK licence could they confirm this strange behaviour 
by replacing the last line of %sqlite.r with:

attempt [delete %test.db]
connect/create %test.db
sql "create table t (c)"
sql "insert into t values (1)"
print mold SQL ["select * from t where c = ?" 1]
wait 2


and encapping it with either enpro or enface. Run both the script 
and the encapped version and compare the output ... I get an empty 
block returned by any statement that makes use of bind variables 
and is encapped. DOing %sqlite.r from an encapped script works fine, 
as does something like:

	do uncompress #{789C...

so my only guess is it's a binding issue of some sort.
Ashley:
16-Mar-2006
Hmm, adding /direct to the example posted previously and changing 
the last part of the INSERT to "... form $1 1 form $1 * 1" seems 
to work properly (100 error-free runs so far). The *only* difference 
then is in this line of the value binding logic:

	unless direct [val: mold/all val]

which if you change it to something like:

	unless direct [p: mold/all val]
	*bind-text sid i p length? p 0


seems to handle more runs before a failure. Thinking that mold/all 
might be the problem I then reran my /direct test with the following 
SQL statement:


 SQL reduce ["insert into t values (?,?,?,?,?)" 1 mold/all reform 
 ["A" 1] mold/all $1 1 mold/all $1 * 1]


which is functionally equivalent to the failing statement ... but 
no failures (after 100 runs). So, the conditions needed to reproduce 
this error [so far] are:

	SQLite library
	INSERT statement using a particular sequence of bind variables
	MOLD/ALL coded / used in a particular manner
	High volume of INSERTs

Now is that an obscure error or what? ;)
Ashley:
17-Mar-2006
But they are not the same way ...

	SQL "insert into t values ('text')
	SQL {insert into t values ('"text"')}

map to:


 SQL ["insert into t values (?)" "text"]	; with /direct refinement

 SQL ["insert into t values (?)" "text"]	; without /direct refinement


The first approach in each case is saying, "I want this value to 
be stored as a SQLite TEXT value which will not be LOADed upon retrieval"; 
while the second is saying, "I want this value to be stored as a 
MOLDed SQLite TEXT value which will be LOADed upon retrieval back 
into a REBOL string value (as opposed to the word 'text)".


A string! statement is strictly literal, it is passed onto SQLite 
with no parsing or conversion. If you want to bind values, use the 
block form ... that's what it's there for!
Ashley:
25-Mar-2006
0.1.8 available at: http://www.dobeash.com/SQLite/sqlite.r


Two main fixes are date bind value handling and concatenated string 
handling (both of which were posted previously as code snippets).
Ingo:
5-Apr-2006
I got an error in the 'sql func ...


** Script Error: length? expected series argument of type: series 
port tuple bitset struct
** Where: switch
** Near: *bind-text sid i val length?

the database is opened with /direct refinement.

The call is:
	sql ["select * from person where guid = ?" guid1]


Where I know, that the dataset with this guid exists, because I have 
just got it from another selsct.
The dataset contains only strings, some of them empty.


Well, this is it: ["h-o-h.org_20060326_182311691_1224" "Urte" "Hermann" 
"Urmeli" "" "" "" "" "" "" "" "" "" "" "Opera ID: 359" "" "" ""]

And I am using the right guid.

Any ideas?
Ingo:
5-Apr-2006
So, the error in one small message: 

>> sql ["select * from person where guid = ?" #"a"]

** Script Error: length? expected series argument of type: series 
port tuple bitset struct
** Where: switch
** Near: *bind-text sid i val length?
Ashley:
7-Apr-2006
If it's only TEXT types you need to encrypt then we could always 
add a /secure refinement to CONNECT that would force encrypt / decrypt 
on all TEXT bind variables. Performance wouldn't be too bad as values 
would only be encrypted [once] on INSERT and SELECT, the actual query 
(which could potentially hit millions of rows) would be comparing 
encrypted strings and would only need to decrypt strings that form 
part of the result set. Very similiar to the overhead that MOLD/LOAD 
currently incur when not using the /direct refinement.
1 / 992[1] 2345678910