• 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: 801 end: 900]

world-name: r3wp

Group: Dialects ... Questions about how to create dialects [web-public]
Maxim:
13-Jan-2011
another thing which helps is to be (rather) fluent or at least aware 
in how REBOL handles the evaluation of words and how to bind words 
to different blocks.


mastering this will help you go at a new level in your dialecting. 
 keep this for your second pass at learning if you're still new to 
REBOL itself.
Group: !REBOL3 ... [web-public]
BrianH:
25-Mar-2010
And if we BIND/no-self on a object with an overriden 'self field 
we can still see it. And if the override 'self is hidden, BIND/self 
doesn't unhide it, it inly unhides the original 'self.
Gabriele:
26-Mar-2010
Ok, so let me try to recap this huge discussion. In R2 we had context! 
and object! as two separate types, although context! was hidden from 
users and only accessible by converting it to object! - conversion 
which was broken because it did not create 'self that object! requires. 
So, instead of fixing this by making context! accessible, it was 
decided to remove context! altogether and add 'self to all contexts, 
and add a bunch of exception refinements to BIND to work around all 
the problems that come out of that?
BrianH:
26-Mar-2010
The part you missed for R3 was that there were no exception refinements 
added to BIND to deal with this at all - they weren't needed. And 
we are proposing to add *one* refinement to BIND, out of a choice 
of two.
BrianH:
27-Mar-2010
Admittedly, you can't do the BIND unhiding trick either, but if you 
roll your own (let's call it 'this), the 'this reference can go in 
another context and you will get the same advantages. Or you can 
bind all the code that needs to refer to 'this before you hide 'this, 
so you won't need to unhide 'this later (normally impossible).
BrianH:
28-Apr-2010
Yeah, but it's a special binding, with just a reference to the context, 
not to a field. The object doesn't have a 'self field. The 'self 
keyword is currently just a side-effect of the BIND and IN functions, 
not something that is really in the object.
BrianH:
28-Apr-2010
(From chat #7216) Some tests pass, others fail. It's a good start.

- The tests in the example code of bug#1549 pass (Ladislav's philosophicals)

- The practical tests don't. In particular, bug#447, bug#1528 (for 
closures), bug#1529 and bug#1552 are still problematic.

- We need a SELFLESS? function (or whatever it should be called) 
to resolve the main downside of the #1549 approach, and we need it 
for the a98 release.

Here are the practical tests that need to pass:

; Objects
ob: object []
print same? ob do bind [self] ob
print same? ob do in ob [self]

; Functions
ob: object [f: func [/x] [do bind/copy [self] 'x]]
print same? ob ob/f
; Can't use the context after the function returns.
; This is not a side effect of Ladislav's proposal.

; Functions with a 'self parameter (#1528)
ob: object [f: func [/self] [do bind/copy [self] 'self]]
print not same? ob ob/f

; Closures (#447)
ob: do closure [x] [bind? 'x] 1
print 1 = ob/x
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Closures with a 'self parameter (#1528)
ob: do attempt [closure [self] [bind? 'self]] 1
print 1 = attempt [ob/self]
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Closures shouldn't bind 'self unless it is a parameter (#447)
print same? self do closure [x] [self] 1
print not same? self do attempt [closure [self] [self]] 1

; Loops (#1529)
ob: repeat x 1 [bind? 'x]
print 1 = ob/x
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Loops with a 'self variable (#1529)
ob: repeat self 1 [bind? 'self]
print 1 = attempt [ob/self]
print not same? ob do bind [self] ob
print not same? ob do in ob [self]

; Loops shouldn't bind 'self unless it's a variable (#1529)
print same? self repeat x 1 [self]
print not same? self repeat self 1 [self]


See also #1552: There needs to be a way to distinguish selfless contexts 
from selfish contexts at runtime (a SELFLESS? function), and selfless 
contexts need to MOLD into DOable syntax (perhaps a different datatype, 
or a flag).
Ladislav:
29-Apr-2010
selfless?: func [context [word! object!]] [
	make object! [
		myself: 'self
		return same? myself first bind [self] context
	]
]
Ladislav:
29-Apr-2010
if we want to have the function faster, this version should suffice:

make object! [
	set 'selfless? func [context [word! object!]] [
		return same? 'self first bind [self] context
	]
]
Ladislav:
29-Apr-2010
optimized:

make object! [
	set 'selfless? func [context [word! object!]] [
		'self =? first bind [self] context
	]
]
Ladislav:
29-Apr-2010
as it looks, this optimization was "too much", since the function 
modifies itself, so either we need to always create a new object, 
like above, or use BIND/COPY at least:

make object! [
	set 'selfless? func [context [word! object!]] [
		'self =? first bind/copy [self] context
	]
]
BrianH:
29-Apr-2010
I use /local self. I was talking about your
    'self =? first bind/copy [self] context
vs. my
    self =? do bind/copy [self] context
Mine has a code-injection risk.
BrianH:
29-Apr-2010
Another way to resolve the risk would be to change the line to this:
    :self =? do bind/copy [:self] context
Ladislav:
3-May-2010
If you remember, once I used a trick to achive the same effect to 
enhance the BIND function
BrianH:
4-May-2010
Steeve, REBOL in general and R3 in particular doesn't have direct 
support for parent objects; we support prototype objects instead, 
which is a completely different thing. So the body of an object isn't 
stored at all, let alone shared; instead, BODY-OF an object creates 
a brand-new block every time from a collection of the key and value 
pairs. There might be some data sharing of the words collection between 
a prototype of an object and derived objects (which might be what 
you meant) to save memory, iirc, but the values are BIND/copy'd.
Maxim:
4-May-2010
in any case, there can be other alternatives too.


the init could manage the hiding.  so that you can bind expanded 
objects, if you have a hold of the original class .
BrianH:
4-May-2010
The only overhead added to objects would be for fields to assign 
the method! values to. The method! values themselves would just have 
their references transferred on MAKE object! - they wouldn't be BIND/copy'd. 
And if you implement them right, they wouldn't even need to be defined 
as part of the object body, or bound to the object explicitly before 
being appended.
BrianH:
5-May-2010
FOREACH has BIND/copy overhead of its code block, not slower speed.
BrianH:
5-May-2010
REPEAT has the same BIND/copy overhead, but REPEAT w number! has 
less work to do, so it's faster. I wouldn't be surprised if REPEAT 
w series! is comparable to FORALL.
BrianH:
5-May-2010
I can understand your REPEAT code being slower than FOREACH: You 
put an extra FIRST in the code block, so the code isn't comparable 
in speed. Compared to FORALL, there's the added BIND/copy overhead.
BrianH:
5-May-2010
>> dt [loop 100000 [repeat x [1 2 3 4] []]]
== 0:00:00.062792
>> dt [loop 100000 [repeat x 4 []]]
== 0:00:00.060991
>> dt [loop 100000 [foreach x [1 2 3 4] []]]
== 0:00:00.064321
>> dt [loop 100000 [x: [1 2 3 4] forall x []]]
== 0:00:00.026746

Gotta love that BIND/copy overhead :(
BrianH:
5-May-2010
You aren't testing code equivalence. FORALL is used in different 
circumstances than FOREACH. If the code is huge it adds to the BIND/copy 
overhead. If you have to use FIRST all the time it slows down FORALL 
because you're not using the right function.
BrianH:
7-May-2010
>> a: [a] same? a in self a
== true

IN something block! is like BIND, not BIND/copy - IN modifies. Don't 
remove stuff from the original.
BrianH:
7-May-2010
I think words are immutable in R3, like integers, tuples and typesets. 
When IN or BIND binds a block I think they replace the words they 
bind with new words that refer to the same symbols, but a new context. 
So IN and BIND never modify words - they replace them.
BrianH:
12-May-2010
No change in syntax or parsing would be required. However, the DO's 
evaluation rules for the set-word expression *would* need to be changed. 
Note that these evaluation rules are *not* performed by a parser, 
so changing parsing would not be required, Paul.


However, this change to the evaluation rules of the DO dialect would 
be so fundamental that we would essentially be changing the semantics 
of the language to that of another language. And that other language 
would resemble Icon more than it would REBOL, semantically. And changing 
the behavior of the SET, LESSER?, ... functions would not be enough 
because DO doesn't actually call those functions directly - it calls 
internal code, which may or may not also be called by those functions.


But this is not a problem, because at least you wouldn't have to 
change the parsing. This means that all you would have to do is write 
your own evaluator and pass the code to that instead of DO. And create 
new versions of all the functions that call DO internally, behaving 
the same but calling your DO replacement instead. And create a context 
to reference those functions, and bind to that context instead of 
the standard system context. Basically, all you have to do is create 
a new dialect on the scale of the DO dialect, using the same REBOL 
parser, but different semantic rules.
Maxim:
2-Aug-2010
yes, but its a refinement, and even then, it still acts "locally" 
within that object (I'm assuming its using function locals on words 
in didn't bind to).
Maxim:
13-Sep-2010
shoudn't resolve have a refinement called /bind  making it easier 
to rebind data to target context in a single pass?
Rebolek:
17-Sep-2010
There's probably some easier way than this, I hope:

>> x: 1
== 1
>> set bind to word! "a" 'x 2
== 2
>> a
== 2
ChristianE:
17-Sep-2010
May I withdraw my suggestion? Don't use is in tight loops:

>> dt [loop 100000 [set load "a" 2]]
== 0:00:02.017813

>> dt [loop 100000 [set bind to word! "a" 's 2]]
== 0:00:00.079424
Henrik:
17-Sep-2010
well, then there has to be a better way to do that. some kind of 
default-bind.
Andreas:
17-Sep-2010
set bind/new to word! "a" self 2
or
set bind/new to word! "a" system/contexts/user 2
BrianH:
21-Sep-2010
Maxim: "shoudn't resolve have a refinement called /bind  making it 
easier to rebind data to target context in a single pass?"

There is a REBIND internal function that hasn't been exported yet. 
Ask Carl or request in CureCode for the function to be exported.
BrianH:
21-Sep-2010
Now for the other binding stuff:


* SET is a low-level function that would be slowed down immensely 
by adding any refinements.

* SET does handle the unbound scenario: It triggers an error. You 
can then handle the error.

* R2 and R3 get their speed from the direct binding model. The core 
speedup of that model is that SET doesn't bind.


* LOAD in R3 is a high-level mezzanine function. It is meant to be 
as fast as possible given its purpose, but being fast is not its 
main goal; user-level flexibility is. Most of the overhead of LOAD 
is in handling all of its various options, as refinements, file extensions 
and script header settings. If you know what you are doing, you can 
always optimize your code by doing it directly instead of having 
LOAD try to figure out that is what you want to do. LOAD is not meant 
for use in tight loops.


* Henrik, ChristianE, the R3 standard answer to the question of how 
to make BIND TO-WORD "a" more efficient or friendly in R3 is this: 
You are encouraged to not program that way in R3. Converting strings 
to words is something you should do once, not all the time in tight 
loops. Your code will be much more efficient if you work in REBOL 
data rather than storing your code in strings and converting at runtime. 
Strings are for data, or script source, not for containing scripts 
at runtime. This is a good rule for all REBOL versions, but especially 
for R3 with its Unicode strings vs. shared UTF-8 words.


* I have recently refactored LOAD so that it is broken into smaller, 
more efficient functions. You might find that those functions would 
work better for you in lower-level code. But this was done to let 
us make LOAD *more* powerful, not less, so the same advice I gave 
above about not using LOAD in tight loops still applies. I don't 
yet know if the new LOAD is faster or slower, but it is safer and 
easier to understand and modify, and you can make your own LOAD replacement 
that calls the same low-level functions if you like. Plus, you get 
compressed scripts :)
Ladislav:
22-Sep-2010
The initialization has to occur in the function body, unfortunately, 
otherwise the R3 protection does not allow BIND to be used, which, 
on the other hand, means, that the IF call is done every time the 
function is called, which means additional overhead
Ladislav:
15-Nov-2010
But, being at it, there is one annoyance I perceive:


1) the variables bound to a function context don't cease to exist 
even when the function is not running
2) code like:
    f: func [/a]['a]
    block: [a]
    bind block f

do not work, while I can do such a bind on my own without needing 
any permission:
    change block f
So, this is clearly just an annoyance, and not a useful feature.
Ladislav:
15-Nov-2010
and, being at it, yet another annoyance of exactly the same kind 
is:

o: make object! [me: 'o]
error? try [bind 'self o] ; == true
bind [self] o; == [self]

, i.e. again, one can bind as wished, so the "feature" is just meant 
to be annoying, not useful
Ladislav:
16-Nov-2010
I am able to bind a block to a function even when the function is 
not running, so pretending that it is impossible is just that: pretending.
Ladislav:
16-Nov-2010
What I wanted to demonstrate was, that:

block: [a]
g: closure [a] ['a]
f: func [a] ['a]
; this works
bind block g
; this does not work
bind block f
; but it can be replaced by this, doing what was requested:
change block f


, i.e. there is no reason why the operation should not work, except 
for the fact that somebody does not want me to do it (ineffectively, 
since I demonstrated, that it can be done anyway
Ladislav:
16-Nov-2010
you can't rebind because definitional binding depends on the order 
of binding operations

 - there are at least two things I do not understand in this sentence:

* "you can't rebind" - I am not trying to "rebind" above

* "because definitional binding depends on the order of binding operations" 
- sure it does, does that mean, that the BIND function should not 
work at all?
BrianH:
18-Nov-2010
R3 objects can't have fields *removed* because that breaks binding, 
but maps can *because* you can't bind to them. Most of the differences 
between maps and objects are because of that difference.
Sunanda:
25-Nov-2010
Are there are practical differences between these two R3 ways of 
extending an object?
    obj: make object! []
    extend obj 'a 1
    bind/new 'b obj obj/b: 2
    probe  obj
     == make object! [
              a: 1
              b: 2
        ]
Steeve:
25-Nov-2010
Extend is a mezz, so that much be slower.

And I always try to avoid GC overheads due to excessive  usage of 
'reduce


Thats why I think bind/new is more capable especially, this form:
>set bin/new 'b obj 2
instead of:
>>bind/new 'b obj obj/b: 2
Andreas:
25-Nov-2010
Besides the readability/performance trade-off, things also start 
to differ when non-true? values are involved:
    obj: make object! []
    extend obj 'a none
    extend obj 'b false
    set bind/new 'c obj none
    set bind/new 'd obj false
    print mold obj
==>
    make object! [
        c: none
        d: false
    ]
Sunanda:
25-Nov-2010
EXTEND is a wrapper for APPEND....So are there any practical advantages 
in using BIND/NEW rather than APPEND ?
    append obj [c: 3]
    == make object! [
        a: 1
        b: 2
        c: 3
    ]


I know right  now there are some differences when messing with PROTECT/HIDE, 
but there are many  CureCodes to go before we'll know if those differences 
are for real.
BrianH:
25-Nov-2010
I like the SET BIND/new trick. There has already been code in the 
mezzanines where such a trick would come in handy, but it had never 
occurred to me. Thanks Steeve!
BrianH:
25-Nov-2010
The practical advantages of the SET BIND/new trick as opposed to 
APPEND is that you don't have to REDUCE a block to be appended. The 
point to the IF :val guard in EXTEND was to screen out false and 
none in GUI code, but that is likely no longer necessary. There was 
a blog where it was suggested that EXTEND be rewritten to work differently, 
but I think that various natives were enhanced instead. EXTEND is 
now a little anachronistic.
Sunanda:
26-Nov-2010
Thanks for the EXTEND vs APPEND vs BIND discussion, guys. It can 
be useful to have different mechanisms that have their own default 
behaviours.


One use of BIND/NEW is that it allows words to be unset when an object 
is created:


    obj: context [bind/new 'word self]   ;; this works, and WORD is UNSET!

    obj: context [word: #[unset!]]       ;; this does not work
    * Script error: word: needs a value
    * Where: make context
    * Near: make object! blk
Maxim:
11-Jan-2011
I think to,  I think the rule is most usefull in cases like bind 
where we need multiple variants of a word to mean different things. 
  in such a case, the  ? should always tend toward the most obvious/usefull 
conditional safe function.   :-)
Oldes:
23-Jan-2011
So far I have this:
my-attempt: funct[code /local val][
	either error? set/any 'val try code [
		val: to-object val 
		do bind [
			print rejoin [

    "!! " val/type  " error: " reduce system/catalog/errors/(val/type)/(val/id) 
    #"^/"
				"!! Where: " val/where #"^/"
				;"!! Near: " val/near  #"^/"
			]
		] val
		false
	][
		:val
	]
] 

my-attempt [debase #ff]
my-attempt [1 / 0]

but not perfect... the Near and Where info is modified :-/
Oldes:
23-Jan-2011
I was using this function in R2:
parse-error:  func[
    error [object!]
    /local type id arg1 arg2 arg3 where err-desc
][
    type: error/type
    id: error/id
    where: mold get/any in error 'where
    either any [
        unset? get/any in error 'arg1
        unset? get/any in error 'arg2
        unset? get/any in error 'arg3
    ][
        arg1: arg2: arg3: "(missing value)"
    ][
        arg1: error/arg1
        arg2: error/arg2
        arg3: error/arg3
    ]
    err-desc: system/error/:type
    rejoin [
        "** " err-desc/type ": "
        reduce either block? err-desc/:id [
            bind system/error/:type/:id 'arg1
        ][
            err-desc/:id
        ]
        newline
        "** Where: " where
        newline
        "** Near: " mold error/near
    ]
]

>> f: does [1 / 0]
>> if error? err: try [f][print parse-error disarm err]
** Math Error: Attempt to divide by zero
** Where: f
** Near: [1 / 0]

In R3 the WHERE and NEAR report is different
BrianH:
4-Mar-2011
set bind/new/copy words obj values
BrianH:
4-May-2011
OK, the problem with that model *in this case* (PROTECT/hide) is 
that we are talking about object fields here, bindings of word values. 
REBOL objects bind their code blocks before executing them. If there 
is going to be any blocking of bindings, at least the object's own 
code needs to be bound first. This means that if you are going to 
make word bindings hidden, you need to do so after the object itself 
has been made, or at least after its code block has been bound. You 
can do this binding with PROTECT/hide, or with some setting in an 
object header, it doesn't matter. Since words are values and their 
bindings are static, being able to create a new word with the same 
binding means that you need access to a word with that binding, with 
*exactly* the same visibility issues as token access. The difference 
in this case between POLA and PROTECT/hide is whether object fields 
are hidden by default or not, not a matter of when they are hidden.
BrianH:
5-May-2011
I'm more concerned with people trying to sneak functions into data, 
which could then use parameters to get access to the original code 
of another function. This can be used for code injection, or for 
getting access to bound words that have since been hidden, or to 
internal contexts. Given that words are often valid data, having 
a special case where they can execute functions by sneaking in a 
bound word is a real concern. However, if that function can't take 
parameters, there is no hacking potential and function code can be 
secure. The workaround if you don't want any functions executed (beyond 
the hacking) could be to unbind words retrieved from data, bind them 
to a known context, or just avoid using DO word or path altogether.
Geomol:
17-May-2011
Is it possible to bind a function's body to a new context in R3? 
In R2, it can be done with

	bind second :f new-context
Ladislav:
17-May-2011
As follows:

    f: make function! reduce [spec body]
    bind body new-context
Geomol:
17-May-2011
I get some errors (under OS X):

>> bind 'body o
** Script error: body is not in the specified context
>> bind [body] o 
== [body]
>> f 1
** Script error: a has no value

My f, body and o are defined this way:

>> f: func [v] body: [v + a] 
>> o: context [a: 1]
Geomol:
17-May-2011
Hm, I did it wrong, I think, but still doesn't work with:

	bind body o
Ladislav:
17-May-2011
>> f: make function! reduce [[v] body: [v + a]]
>> o: context [a: 1]
== make object! [
    a: 1
]

>> bind body o
== [v + a]
Ladislav:
17-May-2011
This needs some thought, Geomol. Actual example:

f1: closure [/local a][a: 1 [a]]
f2: func [blk /local a][a: 2 do blk]
f3: func [blk /local a][a: 3 do bind blk 'a]

>> f2 f1
== 1

>> f3 f1
== 3
BrianH:
17-May-2011
Recursive functions in R2 work by pushing the block of values in 
a context onto a stack during the recursive calls, then popping them 
off on return. In R2, function contexts are stack-relative, which 
makes word dereferencing 27% slower relative to object contexts, 
but function calls in general faster. Closures bind to object contexts, 
which are recreated with every function call.
Geomol:
19-May-2011
I found an bad effect of not binding words in blocks at all, before 
the block is evaluated. Functions like LOOP take 2 args, count and 
block. By not binding the block content before it's evaluated, the 
count arg local to LOOP is found, if a count var is used in the block.

So I guess the REBOL early bind of words is better.
Geomol:
20-May-2011
Yeah, they will be reused. But the way, REBOL do it, if you have 
an application, that do a lot of block parsing for example, with 
new words coming in all the time, then that global context will just 
grow and grow. In reality, it will probably come to an end, as there 
are a finite number of words in a human language, if that's what 
being parsed.


If words were not bound by just being loaded, but only when evaluated 
(or compiled, if that's the case), then parsing blocks would not 
produce any unset! words in the global context. But a consequence 
of this is, that blocks of code being sent to a function (like LOOP), 
will be able to see the words local to that function, unless the 
block is first bound outside the function, like

	count: 1
	loop 10 bind [print count] 'count
, which will then print the number 1 10 times.
BrianH:
20-May-2011
TO-HEX generates an issue!, which is a word type in R3. Yes, you 
can even bind them.
BrianH:
26-May-2011
Geomol, about native-op!, native-closure! and native-action!, these 
won't be necessary. Functions of the native! type don't need to bind 
their bodies to contexts, so they don't need the feature that makes 
closures closures. Ops and actions both redirect to the actual implementing 
function, which in the case of actions is an internal native associated 
with the type of the first argument, and in the case of op is a (at 
the moment only native) function provided at op creation time. If 
you wanted to allow the creation of user-defined datatypes with function!, 
closure! or command! implementations of the type's actions, the regular 
action! functions would still redirect to these implementations. 
Similarly, the regular op! type could be extended to support redirecting 
to other function types without needing the creation of a new function 
type.
Ladislav:
26-May-2011
Functions of the native! type don't need to bind their bodies to 
contexts

 - in that sense, natives behave both as functions and as closures 
 at the same time. That is not as a big of an exception, as it may 
 look, e.g.:

    f: func [][]

behaves as a closure, similarly as

   g: func [x y][add :x :y]


, simply because in such simple cases it is not discernible whether 
the given "function" is a function or a closure
BrianH:
28-May-2011
Sunanda, agreed, and also about it being clunky, particularly because 
USE has both COPY/deep and BIND/copy overhead in R3. ASSERT/type 
[local none!] is still the most efficient method.
Ladislav:
8-Oct-2011
Brian, regarding BIND, I mean e.g. this:

>> f: make function! compose/only [[a b c](body: [a do c])]
>> a: first body
== a

>> f 1 1 [a + b]
** Script error: b has no value
** Where: do f
** Near: do c

>> f 1 1 bind [a + b] first body
** Script error: none word is not bound to a context
** Where: bind
** Near: bind [a + b] first body
BrianH:
8-Oct-2011
Yeah, it is an interesting efficiency hack that MAKE function! does 
a BIND on the function body instead of a BIND/copy. It does mean 
that you need to be careful with the runtime accessibility of your 
source though.
Ladislav:
8-Oct-2011
MAKE function! does a BIND on the function body instead of a BIND/copy 
- it is not only for efficiency, it is actually the proper way even 
for safety
Ladislav:
8-Oct-2011
I do like that. but, nevertheless, the MAKE function is able to bind, 
while I am not, which proves, that it is just an artificial, (not 
making anything more secure) and annoying limitation
BrianH:
8-Oct-2011
it is actually the proper way even for safety

 - Why so? Once the function is made, security dictates that the accessibility 
 of its bound body should be limited. If you can get a bound body, 
 you can trace through the bindings to get access to any internal 
 code it references. That is why R3's BODY-OF does something like 
 an UNBIND/deep COPY/deep. If MAKE function! does a BIND rather than 
 a BIND/copy, that means that any extant references to the original 
 body block argument are a potential security hole unless they are 
 contained.
Ladislav:
8-Oct-2011
But, that does not solve the BIND annoyance.
Ladislav:
8-Oct-2011
In my opinion, BIND should simply obey and not annoy with error message 
in such a case
Ladislav:
8-Oct-2011
As said, if BIND does not do it for me, I can do it on my own using 
CHANGE, so no safety can be gained
BrianH:
8-Oct-2011
On second thought, allowing BIND to take a function! for its context 
argument would allow you to get around the security protections of 
BODY-OF.
BrianH:
8-Oct-2011
But you can already BIND to a word bound to a function context. BODY-OF 
just keeps you from getting access to a word bound to a function 
context from outside the function. As long as you control access 
to the original code block you are secure.
Ladislav:
8-Oct-2011
But you can already BIND to a word bound to a function context.

 - actually, I cannot, if the function isn't already running (in that 
 case BIND refuses to do that)
BrianH:
8-Oct-2011
>> bind 'a do func [/a] ['a]
** Script error: a is not in the specified context
** Where: bind
** Near: bind 'a do func [/a] ['a]


Well, then you don't have to be as careful with letting bound function 
words leak I guess.
Ladislav:
8-Oct-2011
But, that is wrong, since when you let the word out, you can bind, 
just not using the BIND function (you need to use CHANGE for that)
BrianH:
8-Oct-2011
>> head change [1] 'a
== [a]
>> head change [1] #"a"
== [#"a"]


With BIND, you can leak the 'a word and get access to the 'b word 
from that same context. You can't do that with CHANGE.
BrianH:
8-Oct-2011
(Sorry, internet outage)

Sure it is, in some cases. What if 'a is harmless, but 'b refers 
to a password? If you can only CHANGE, not BIND, then leaking a word 
is only as dangerous as leaking what that word refers to. If you 
can BIND using that word as a context, you can get access to *every* 
value referred to by that context, not just the one. So it's still 
potentially a problem to leak a single word (depending on what gets 
assigned to that one word), but not as bad a problem as it could 
be.
Ladislav:
9-Oct-2011
I am still sure, that disabling BIND in such cases is totally useless. 
(besides, when the function is not running, you cannot obtain the 
value of 'b even if you obtained 'b)
BrianH:
9-Oct-2011
Oh, that's what you meant. I was asking specifically about the particular 
question I asked. It sounded like you were saying you had a way to 
do a BIND without BIND. If so, that would be an interesting trick, 
but also a security hole. I'm more interested in the trick though, 
if it exists.
Ladislav:
9-Oct-2011
Not much of a trick is needed. The above statement (when proven, 
which is easy), proves, that the disabling of BIND for non-running 
function words is not a security measure.
BrianH:
9-Oct-2011
Let's ignore the function context aspect of it all, and simplify 
the problem. If you have a word bound to a context, and want to get 
access to another word bound to the same context, and don't have 
access to the BIND or IN functions at all, how would you do it?
Ladislav:
9-Oct-2011
(Even though the BIND function is "crippled*, but, as proven by the 
above statement, unreasonably so.)
Ladislav:
9-Oct-2011
Yes, but my intent was to prove, that the BIND crippling is unreasonable, 
which is provable.
Ladislav:
9-Oct-2011
Above you mentioned, that the reson is this:


- if I had access to a 'var-a variable bound to the F's context, 
and if I were able to do "some harm" having another variable 'var-b 
bound to the F's context, then that is a good reason why to cripple 
BIND, to not give me the access to the 'var-b bound to the F's context 
as well when the function is not running.

 As stated, I can disprove that as a reason.
Ladislav:
9-Oct-2011
OK, I will cite you exactly:


Sure it is, in some cases. What if 'a is harmless, but 'b refers 
to a password? If you can only CHANGE, not BIND, then leaking a word 
is only as dangerous as leaking what that word refers to. If you 
can BIND using that word as a context, you can get access to *every* 
value referred to by that context, not just the one. So it's still 
potentially a problem to leak a single word (depending on what gets 
assigned to that one word), but not as bad a problem as it could 
be.
BrianH:
9-Oct-2011
OK, so you don't have a solution to that problem (darn, I was looking 
forward to that), but you have a proposed proof that it doesn't matter 
because you can't exploit it until the function is running. And since 
the BIND restriction when the function isn't running doesn't apply 
when the function *is* running later, even when applied to the same 
word, then the ban on BIND to a function-context-bound word when 
the function isn't running has no security benefit.


But the ban on BIND to the function! value *itself* still has value, 
because it would defeat the efforts to prevent any bound words from 
leaking out of the function from helping. Otherwise it would be unsafe 
to let untrusted code call safe functions because they would need 
to have a reference to the function in order to call it.
Ladislav:
9-Oct-2011
But the ban on BIND to the function! value *itself* still has value, 
because it would defeat the efforts to prevent any bound words from 
leaking out of the function from helping. 
 - another disprovable statement
BrianH:
9-Oct-2011
The "But the ban on BIND to the function! value *itself*..." statement 
refers to this:
>> not find second types-of :bind function!
== true


The BIND function doesn't accept function! values for its context 
argument. The reason for this is so that functions can prevent access 
to their context from leaking to code *that the function calls* that 
could be exploited while the function is running. All the function 
has to do is not leak bound words, and it's safe. If that doesn't 
work, please show how.
Ladislav:
9-Oct-2011
To remind you, I am and was always referring to this:

>> f: func [a b] ['a]
>> bind [b] f 1 2
** Script error: none word is not bound to a context
** Where: bind
** Near: bind [b] f 1 2

The above is unrelated
BrianH:
9-Oct-2011
No, the above is the exact reason for:
>> not find second types-of :bind function!
== true
Ladislav:
9-Oct-2011
But, the reasons for disallowing the functions as the BIND arguments 
have actually a similar flaw.
BrianH:
9-Oct-2011
a: func [code /stuff] [stuff: "something secret, not a literal string" 
code]


With just a reference to :a, bind 'stuff to the function context. 
The function could be running or not when you get access to the bound 
word 'stuff. The exploit code can then be passed to the function 
in its code argument, which would then have access to the contents 
of 'stuff because the function is running.
BrianH:
9-Oct-2011
No, seriously, I meant it. How do you do this without BIND 'stuff 
:a ?
BrianH:
9-Oct-2011
a func [] [print get bind 'stuff :a]
Ladislav:
9-Oct-2011
OK, but nothing of that kind applies to the case of BIND [...] 'some-variable
BrianH:
9-Oct-2011
then the ban on BIND to a function-context-bound word when the function 
isn't running has no security benefit
 :)
801 / 99212345678[9] 10