Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Bug! in assignment to date! values with stacked set-path values

 [1/25] from: al::bri::xtra::co::nz at: 12-Nov-2002 20:04


Here's an example:
>> x: now/date
== 12-Nov-2002
>> x/day: 1 ; Try individually; OK!
== 1
>> x
== 1-Nov-2002
>> x/month: 1 ; Try individually; OK!
== 1
>> x
== 1-Jan-2002 ; And the expected value is shown.
>> x: now/date ; Get fresh value.
== 12-Nov-2002
>> x/month: x/day: 1 ; Now stack up the assignments.
== 1 ; correct value is returned, but...
>> x
== 12-Jan-2002 ; Note that only the MONTH is altered...
>> x: now/date ; Get fresh value.
== 12-Nov-2002
>> x/day: x/month: 1 ; Reverse the order....
== 1
>> x ; Note that only the DAY is altered...
== 1-Nov-2002 It's buggy on Rebol/Core, Rebol/View, Rebol/Base and all the beta versions. The work around for now is to separate the assignments, as shown in the first few steps. I've just sent this in to feedback. Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [2/25] from: lmecir:mbox:vol:cz at: 12-Nov-2002 9:46


Hi Andrew, ----- Original Message ----- From: "Andrew Martin" Subject: [REBOL] Bug! in assignment to date! values with stacked set-path values
> >> x: now/date ; Get fresh value. > == 12-Nov-2002 > >> x/month: x/day: 1 ; Now stack up the assignments. > == 1 ; correct value is returned, but... > >> x > == 12-Jan-2002 ; Note that only the MONTH is altered...
This is an artifact that is caused by immutability of dates. (you may remember the discussion on the subject) The x/month: 1 expression is only a hack, no real mutation occurs. Exactly the same hack can be written to modify the bits of integer numbers as I have shown. Regards -L

 [3/25] from: carl:cybercraft at: 12-Nov-2002 23:31


It's not just dates Andrew...
>> a: 1.2.3
== 1.2.3
>> a/1: a/2: 4
== 4
>> a
== 4.2.3 Carl. On 12-Nov-02, Andrew Martin wrote:
> Here's an example: >>> x: now/date
<<quoted lines omitted: 27>>
> ICQ: 26227169 http://valley.150m.com/ > -><-
-- Carl Read

 [4/25] from: rotenca:telvia:it at: 12-Nov-2002 14:45


Hi Ladislav, Andrew, Carl
> This is an artifact that is caused by immutability of dates. (you may > remember the discussion on the subject) The > > x/month: 1 > > expression is only a hack, no real mutation occurs. Exactly the same hack > can be written to modify the bits of integer numbers as I have shown.
It seems to me that the mutation hack is not enough to explain this. The problem is that all the value are pre-fetched before the first assign start, else with or without mutation the result should be right. Instead, the pre-fetch works only with mutable values. The bug is prefetch the value of set-path. Neither parens can correct the problem. Look at this:
>> a: "aaa" probe a/2: (a: "bbb" #"c") a
aca == "bbb" As you can see the a/2 continue to refer to the old string "aaa" also when the parens block has changed the 'a value with "bbb". I can be wrong but i do not see any mutation hack here. --- Ciao Romano

 [5/25] from: joel::neely::fedex::com at: 12-Nov-2002 8:09

Re: Bug! in assignment to date! values with stacked set-pathvalues


Hi, Ladislav, Let's not start *that* again!!! ;-) In addition, I don't think that dates are the issue here. Ladislav Mecir wrote:
> Hi Andrew, > ----- Original Message -----
<<quoted lines omitted: 8>>
> > == 12-Jan-2002 ; Note that only the MONTH is altered... > This is an artifact that is caused by immutability of dates...
Instead of pointing the WayBack machine to "Mutability", let's set it to "Referential Transparency" instead. The principle of RT is that expressions which yield equivalent results should be freely interchangeable without altering the net value. Since 1 + 1 and 2 are equivalent expressions, we'd expect the larger expressions pick "abcde" 1 + 1 and pick "abcde" 2 to yield equivalent values. A notation/implementation in which thing1: someval yields a resulting value equivalent to someval and yet thing2: thing1: someval behaves differently from thing1: someval thing2: someval defies both the principle of RT and (for those who claim that REBOL is for non-programmers) what I believe most "normal humans" would expect from such a rewriting, as REBOL normally allows one to "chain" setting expressions freely (as long as the result of each setting expression is equivalent to the set value):
>> x/2: a: foo/month: b: 1
== [0 1 0]
>> x
== [0 1 0]
>> a
== 1
>> foo
== 12-Jan-2002
>> b
== 1 The disclaimer, of course, is due to the fact that setting X/2 yields a value that is *not* equivalent to 1, but in the case of FOO/MONTH the value yielded *is* equivalent to 1! As with the concurrent discussion of REVERSE (but even more so in this case), it's distressing to have specific instances of *very* non-intuitive behavior marring an otherwise nice notation, when the user has access to no documentation explaining such cases! As a demonstration of my "even more so" position, consider the following ...
>> foo: now/date
== 12-Nov-2002
>> blk: [foo/month: 1]
== [foo/month: 1]
>> do blk
== 1
>> foo
== 12-Jan-2002
>> foo: now/date
== 12-Nov-2002
>> foo/day: do blk
== 1
>> foo
== 1-Nov-2002
>> foo: now/date
== 12-Nov-2002
>> x: do blk foo/day: x
== 1
>> foo
== 1-Jan-2002
>> foo: now/date
== 12-Nov-2002
>> foo/day: do blk
== 1
>> foo
== 1-Nov-2002 ... which shows the presence of hidden state that can cause the effect we're discussing to be buried arbitrarily deeply! I really have to regard this as a serious flaw of documentation (at least!), and respectfully repeat my passionate request for the kind of official, authoritative documentation that would allow users to understand what is happening and why! (I have my own opinions, but they're not authoritative!) -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]

 [6/25] from: lmecir:mbox:vol:cz at: 12-Nov-2002 17:22


Hi Joel,
> I really have to regard this as a serious flaw of documentation > (at least!), and respectfully repeat my passionate request for > the kind of official, authoritative documentation that would > allow users to understand what is happening and why!
My POV differs from yours in two points: a) I think, that the situation is a result of a "hack solution". The strange behaviour looks like being unexpected not just by users, but by implementors too (IMO). This can (at least for me) explain, why it isn't documented. b) The behaviour looks like not being designed with these effects in mind and it needs a second thought. That is why I am not asking for a documentation change/addendum. Best regards -L

 [7/25] from: joel:neely:fedex at: 12-Nov-2002 11:16

Re: Bug! in assignment to date! values with stackedset-pathvalues


Hi, Ladislav, Pardon my disagreeing, but I think we're really agreeing! ;-) (I think perhaps I used too much shorthand, and I'm too pessimistic!) Ladislav Mecir wrote:
> Hi Joel, > > I really have to regard this as a serious flaw of documentation
<<quoted lines omitted: 5>>
> The "strange" behaviour looks like being unexpected not just by > users, but by implementors too (IMO)...
...
> b) The behaviour looks like not being designed with these effects > in mind and it needs a second thought... >
I included the "(at least!)" to hint that I suspect this was the result of some ad hoc implementation choice(s), rather than a consequence of strategic design. I had originally worded my views a bit more strongly, but toned them down before hitting "Send" to avoid leaving the impression that I was REBOL-bashing. Sorry if I was too elliptic!
> This can (at least for me) explain, why it isn't documented. >
But there are lots of things that aren't documented! The lack of authoritative specification for what the built-in features of the language are *supposed* to do is IMHO a significant impediment to its adoption in the larget world of professional programming. When faced with the question of "What does this do?": - Computing Scientists say, "Let's derive it from basic principles!" - Software Engineers say, "Let's look it up in the specification!" - Hackers say, "Let's try it and see what happens!"
> That is why I am not asking for a documentation change/addendum. >
I think it would be easier to get a description of what REBOL currently does (and *then* discuss possible changes) than to begin with a request for changes in the absence of any clear statement of intent. Past discussions about cases where REBOLS behavior has surprised its users (even the most supportive ones) have drawn a response of, "Let REBOL be REBOL!" Hence my position of, "OK! Then first tell me clearly what REBOL is!" However, I'm sure we agree in the hope that documenting REBOL's current behavior wouldn't be the end of the conversation!!! -jn- -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446

 [8/25] from: lmecir::mbox::vol::cz at: 13-Nov-2002 13:58


Hi,
> When faced with the question of "What does this do?": > > - Computing Scientists say, "Let's derive it from basic principles!"
Yes, I like this one and a lot of list members at least tried to pretend, that this was the case.
> - Software Engineers say, "Let's look it up in the specification!"
This is more desirable, than the last one, but...
> - Hackers say, "Let's try it and see what happens!"
This is what happened, (at least in this case).
> I think it would be easier to get a description of what REBOL > currently does (and *then* discuss possible changes) than to begin > with a request for changes in the absence of any clear statement of > intent.
Well, the question is, if we *can* get that. If this was an unknown feature (for implementors), they couldn't have documented it. I think, that the only complete behaviour documentation is the interpreter. (or the source code of it, which we aren't supposed to get, are we?) Every software project can contain some bugs. What you are asking for is some form of specification, which was used to build the interpreter. I don't know, whether this is/isn't considered a trade secret? Moreover, there is still a possibility, that such a thing isn't complete.
> Past discussions about cases where REBOLS behavior has > surprised its users (even the most supportive ones) have drawn a > response of, "Let REBOL be REBOL!" Hence my position of, "OK! Then > first tell me clearly what REBOL is!"
I think, that instead of letting REBOL be whatever, it is more useful to propose an improvement/ask for a feature that we think is missing. (like a referential transparency etc.) The only trouble is, that every user has his/her own list of preferences and they may be incompatible. But, let me play a devill's advocate: "REBOL is a moving target.":-)
> However, I'm sure we agree in the hope that documenting REBOL's > current behavior wouldn't be the end of the conversation!!!
I think, that it neither would be the start nor the end of the conversation, because even now we may say, that some features are documented, but the documentation isn't in agreement with the real state of affairs! Curiously, some things are better than the documentation is suggesting.

 [9/25] from: lmecir:mbox:vol:cz at: 13-Nov-2002 18:16

Re: Bug! in assignment to date! values with stacked set-path values


Hi Romano, I tried to tell, that the behaviour was caused by the fact, that the whole thing was only a hack. The hack was most probably not well thought out and the same hack could have been made for integers and has been made for issues.
> It seems to me that the mutation hack is not enough to explain this. The > problem is that all the value are pre-fetched before the first assign
start,
> else with or without mutation the result should be right. Instead, the > pre-fetch works only with mutable values. The bug is prefetch the value of > set-path.
You are right. The behaviour can be corrected, although that might influence the speed of the interpreter...
> Neither parens can correct the problem. > Look at this: > > >> a: "aaa" probe a/2: (a: "bbb" #"c") a > "aca" > == "bbb" > > As you can see the a/2 continue to refer to the old string "aaa" also when
the
> parens block has changed the 'a value with "bbb". I can be wrong but i do
not
> see any mutation hack here. > > --- > Ciao > Romano
Ah, I didn't read your whole post, sorry. This is interesting and it is a proof of the fact, that the whole path business is a hack in Rebol (no surprise). When we are at it, we shall ask RT to change the path business more thoroughly to introduce referential transparency. I am afraid, that this change will affect the way Rebol parser (make block! / load) works, because I would suggest to not treat #"(" and #")" as ordinary delimiters. Instead Rebol should treat them as "forbidden" characters, which aren't allowed to occur in words. Nevertheless, a/(1 + 2) should differ from a / (1 + 2) , where the former can be treated as a path, while the latter as an expression, which divides A by 3. What do you think about the fact, that the difference is small, which may lead to confusions? -L

 [10/25] from: rotenca:telvia:it at: 14-Nov-2002 12:22


Hi Ladislav,
> You are right. The behaviour can be corrected, although that might influence > the speed of the interpreter...
Yes, but func are already fetched twice, why not path?
> When we are at it, we shall ask RT to change the path business more > thoroughly to introduce referential transparency. I am afraid, that this > change will affect the way Rebol parser (make block! / load) works, because > I would suggest to not treat #"(" and #")" as ordinary delimiters. Instead > Rebol should treat them as "forbidden" characters, which aren't allowed to > occur in words.
I don't undertand well why. Can you make an example?
> Nevertheless, > a/(1 + 2)
<<quoted lines omitted: 4>>
> What do you think about the fact, that the difference is small, which may > lead to confusions?
the problem is general. Many cases in Rebol are of this nature: 2/ 1 2 / 1 2 /1 --- Ciao Romano

 [11/25] from: lmecir:mbox:vol:cz at: 14-Nov-2002 14:02


Hi Romano,
> > When we are at it, we shall ask RT to change the path business more > > thoroughly to introduce referential transparency. I am afraid, that this > > change will affect the way Rebol parser (make block! / load) works,
because
> > I would suggest to not treat #"(" and #")" as ordinary delimiters.
Instead
> > Rebol should treat them as "forbidden" characters, which aren't allowed
to
> > occur in words. > > I don't undertand well why. Can you make an example?
the example is below:
> > a/(1 + 2) > >
<<quoted lines omitted: 4>>
> > , where the former can be treated as a path, while the latter as an > > expression, which divides A by 3.
The reason is this: a/(1 + 1): 5 should be treated as a/2: 5 IMO

 [12/25] from: rotenca:telvia:it at: 14-Nov-2002 15:41


Hi Ladislav,
> The reason is this: > > a/(1 + 1): 5 > > should be treated as > > a/2: 5
Yes, i undertand this. What i do not understand is what you means with "make #"(" a forbidden char in words". Are you asking something as: to-word "(" ;== error! And if this is the case, why? I'm also asking myself if this notation: a/(1 + 1) ;== a/2 is compatible with the less agressive evaluation of new betas. What do you think? --- Ciao Romano

 [13/25] from: lmecir:mbox:vol:cz at: 14-Nov-2002 16:31


Hi Romano,
> What i do not understand is what you means with "make > #"(" a forbidden char in words".
It means, that [(a)] should contain a paren! containing a word as it did, but (a)/(b) shall differ from (a) / (b), i.e. parens shall be treated specifically - neither as possible word characters, nor as ordinary delimiters. Currently we have: length? [(a)/(b)] ; == 3 , while I am proposing, that we should get: length? [(a)/(b)] ; == 1 and type? first [(a)/(b)] ; == path! OTOH, it is OK to obtain: length? [(a) / (b)] ; == 3 What do you think? One may try to check an analogical situation: [a]/[b] versus [a] / [b]. What would be the best solution in that case?
> Are you asking something as: > > to-word "(" ;== error! > > And if this is the case, why?
This case doesn't matter, any solution is acceptable to me.
> I'm also asking myself if this notation: > > a/(1 + 1) ;== a/2 > > is compatible with the less agressive evaluation of new betas. What do you > think?
I would suggest even less aggressive evaluation: if a word is evaluated, like e.g. a , the result should be the same as the result of :a with *exactly* one exception: if A is a function, then the function should be evaluated in the former case. I am sure, that this kind of word evaluation isn't incompatible with the suggested path evaluation change. Ciao -L

 [14/25] from: rotenca:telvia:it at: 14-Nov-2002 18:12


Hi Ladislav
> It means, that [(a)] should contain a paren! containing a word as it did, > but (a)/(b) shall differ from (a) / (b), i.e. parens shall be treated > specifically - neither as possible word characters, nor as ordinary > delimiters.
...
> This case doesn't matter, any solution is acceptable to me.
Only this? Well: everything was clear from the beginning. :-)
> OTOH, it is OK to obtain: > > length? [(a) / (b)] ; == 3 > > What do you think?
I agree. I should like at least to use compose on path: b: 1 compose a/(b) ;== a/1 and get-word in this case:
>> x: func [/a][a] >> b: 'a;== a >> x/:b ;==true
Now the latter print none as it would called without any refinement and this seems to me a bug.
> One may try to check an analogical situation: [a]/[b] versus [a] / [b]. What > would be the best solution in that case?
Is a too radical proposal the following? [[a] 2]/[a] ; ==2 [a 2 b 3]/b ; ==3 a: [[a] 1 [b] 2] a/[b];==2 a/([b]) ;==2 Going in this direction we'll can embed a whole Rebol program in a path! instead of a block! :-) --- Ciao Romano

 [15/25] from: lmecir:mbox:vol:cz at: 15-Nov-2002 8:07


Hi Romano,
> Yes, but func are already fetched twice, why not path?
(-: It looks to me, that we always want the opposite of the actual implementation! :-) I think (Praetera censeo), that functions should be fetched just once and that a: func [x] [type? :x 1] b: func [x] [type? :x 2] a a: :b Should yield 1 (Carthaginem esse delendam). Joel can call my request "the principle of the least surprise", but there is another reason to change the current behaviour: we can avoid some nasty errors/interpreter crashes/bugs this way. OTOH, set-paths are different animals. a: "1" a/1: (a: "3" #"2") a Here everybody is surprised, that the last operation, which is the path-set somewhat magically "occurs" (at least partially) before the paren! evaluation, which, again, seems to violate "the principle of the least surprise". Nevertheless, paths can be evaluated like above and it makes perfect sense to me: a: make object! [f: does [a: make object! [f: does [2]] 1]] a/f ; == 1 This makes perfect sense to me, although: probe a make object! [ f: func [][2] ] Another thing I want to mention is, that while a: "12" a/1: #"3" ; == "32" the same operation used for dates yields: a: now a/day: 1 ; == 1 , which doesn't look unified. -L

 [16/25] from: rotenca:telvia:it at: 18-Nov-2002 12:19


Hi Ladislav
> I think (Praetera censeo), that functions should be fetched just once and > that > > a: func [x] [type? :x 1] > b: func [x] [type? :x 2] > a a: :b > > Should yield 1 (Carthaginem esse delendam).
I agree.
> Nevertheless, paths can be evaluated like above and it makes perfect sense > to me:
Do you means that set-path should be fetched only one time? I think that the problem with path could arise from the fact that set-path does not exists as true datatype!, it is only the last item in the path that make rebol thinks it is a set-path. To truely understand the path, it should evaluate the path itself to find its real meaning. The result is a strange behaviour: a set-path which works like a path x: func [/b][3] type? first [x/b:];== set-path! x/b: ;==3 in the last istruction no set action has been done, the last set-path has been used like a normal path. This happens, i think, because type? looks only at the form of path and it see a set-word, while evaluation sees a function call and a refinement!. Another strange thing: :x ;== function? :x/b ;== 3
> the same operation used for dates yields: > > a: now > a/day: 1 ; == 1 > > , which doesn't look unified.
this is for me the mutation hack at work. --- Ciao Romano

 [17/25] from: lmecir:mbox:vol:cz at: 18-Nov-2002 13:09


Hi Romano,
> > Nevertheless, paths can be evaluated like above and it makes perfect
sense
> > to me: > > Do you means that set-path should be fetched only one time?
I mean, that paths should be evaluated differently, than set-paths (the order of evaluation should be different for these two datatypes).
> I think that the problem with path could arise from the fact that set-path > does not exists as true datatype!, it is only the last item in the path
that
> make rebol thinks it is a set-path.
I don't agree with that, every Rebol datatype has got a type attribute attached to it, IMO.
> The result is a strange behaviour: a set-path which works like a path > > x: func [/b][3] > type? first [x/b:];== set-path! > x/b: ;==3
This is unexpected, but it may be justified as an attempt to "do something meaningful" instead of firing an error.
> Another strange thing: > :x ;== function? > :x/b ;== 3
This is consistent with something like a/:i, when the interpreter considers such a thing to be a path: type? first [:x/b] ; == path! Ciao -L

 [18/25] from: rotenca:telvia:it at: 18-Nov-2002 14:42


Hi Ladislav
> > Do you means that set-path should be fetched only one time? > > I mean, that paths should be evaluated differently, than set-paths (the > order of evaluation should be different for these two datatypes).
OK!
> > I think that the problem with path could arise from the fact that set-path > > does not exists as true datatype!, it is only the last item in the path > that > > make rebol thinks it is a set-path. > > I don't agree with that, every Rebol datatype has got a type attribute > attached to it, IMO.
Yes: load set it, but it can only set it with a rule: it ends with #":". The evaluation then can demonstrate another thing: that it was not a set-path but a function call with refinement.
> > The result is a strange behaviour: a set-path which works like a path > >
<<quoted lines omitted: 3>>
> This is unexpected, but it may be justified as an attempt to "do something > meaningful" instead of firing an error.
I do not think the same. Here the attempt is not set something, but only to evaluate the path. If a set-path is by default "set the value referenced by the path" this construct should trigger an error or a crash. Obviously this can be corrected adding an error! ad hoc, but ist shows for me the interpreter behaviour.
> > Another strange thing: > > :x ;== function? > > :x/b ;== 3 > > This is consistent with something like a/:i, when the interpreter considers > such a thing to be a path: > > type? first [:x/b] ; == path!
Yes, get-path does not exist. The problem for me is that using a function with a refinement and using a function without any refinement are two different things at all, if one use a get-word. Often I'm asking myself: what are advantages of refinements in functions? Often i see only the bad side. --- Ciao Romano

 [19/25] from: lmecir:mbox:vol:cz at: 18-Nov-2002 16:37


Hi Romano,
> > > The result is a strange behaviour: a set-path which works like a path > > >
<<quoted lines omitted: 3>>
> > > > This is unexpected, but it may be justified as an attempt to "do
something
> > meaningful" instead of firing an error. > > I do not think the same. Here the attempt is not set something, but only
to
> evaluate the path. If a set-path is by default "set the value referenced
by
> the path" this construct should trigger an error or a crash. Obviously
this
> can be corrected adding an error! ad hoc, but ist shows for me the
interpreter
> behaviour.
Yes, you are right. This shows the way how the interpreter is built. Nevertheless, there are at least two cases, when I would consider it a bug. The first one is the subject of this thread and the second one is the case of two-times-fetched functions.
> Often I'm asking myself: what are advantages of refinements in functions? > Often i see only the bad side.
The refinements have big disadvantages, as I see it. Some disadvantages: 1) the function must test, how it has been called, although that information has already been processed to get the arguments 2) the refinement system works well only if any refinement combination is legal , otherwise the function must check the combination on its own The trouble is, that the refinements have advantages too. The main advantage is a lower pollution of the system dictionary.

 [20/25] from: g:santilli:tiscalinet:it at: 18-Nov-2002 15:28


Hi Romano, On Monday, November 18, 2002, 2:42:45 PM, you wrote:
>> I don't agree with that, every Rebol datatype has got a type attribute >> attached to it, IMO.
RPT> Yes: load set it, but it can only set it with a rule: it ends with #":". RPT> The evaluation then can demonstrate another thing: that it was not a set-path RPT> but a function call with refinement. I agree with Ladislav.
>> obj: context [a: 1 b: 2] >> p: to path! [obj a]
== obj/a
>> do reduce [p]
== 1
>> p: to path! [obj a:]
== obj/a:
>> do reduce [p 2]
** Script Error: Invalid path value: a ** Near: obj/a: 2
>> p: to set-path! [obj a]
== obj/a:
>> do reduce [p 2]
== 2
>> p: to set-path! [obj a:]
== obj/a::
>> do reduce [p 2]
** Script Error: Invalid path value: a ** Near: obj/a:: 2 In particular:
>> f: func [/ref] [1] >> p: to path! [f ref]
== f/ref
>> do reduce [p]
== 1
>> p: to path! [f ref:]
== f/ref:
>> do reduce [p]
== 1
>> p: to set-path! [f ref:]
== f/ref::
>> do reduce [p]
== 1
>> p: to set-path! [f ref]
== f/ref:
>> do reduce [p]
== 1 which shows that REBOL is just being very permissive for functions with refinements. RPT> I do not think the same. Here the attempt is not set something, but only to RPT> evaluate the path. If a set-path is by default "set the value referenced by RPT> the path" this construct should trigger an error or a crash. Obviously this RPT> can be corrected adding an error! ad hoc, but ist shows for me the interpreter RPT> behaviour. I think that for both set-path! and path!, first of all REBOL determines the value of the first word. Then, it "decodes" the path up until the last value, and then it decides what to do based on the type of the path. Probably, as soon as it finds out that the first word refers to a function!, it passes the control to the code handling functions, that simply does not "know" about set-path!s and so behaves like it was a path!. RPT> Often I'm asking myself: what are advantages of refinements in functions? Economy of expression. Without refinements, using functions like OPEN would require a lot of arguments. Also, one could not extend functions retaining compatibility like it was done with MOLD (/ALL refinement) or LOAD (/LIBRARY refinement) etc. Of course, if we had a formal specification for the REBOL language and the function interpreter, it would be easier to understand what is a design decision and what is just an implementation issue. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [21/25] from: rotenca:telvia:it at: 18-Nov-2002 17:50


Hi Ladislav
> Some disadvantages: > > 1) the function must test, how it has been called, although that information > has already been processed to get the arguments > > 2) the refinement system works well only if any refinement combination is > "legal", otherwise the function must check the combination on its own
The 3) problem is confusion with path. The / divisor for function refinements forces the interpreter to discard all refinement which follow a function call in a path: a: func[/b /c][[[1]]] a/b/c/1/1; == [[1]] with a different char, for example "!" we could write: a: func[!b !c][[[1]]] a!b!c/1/1;== 1 like in x: [[1]] x/1/1; == 1
> The main advantage is a lower pollution of the system dictionary.
Only because all loaded local words are added to the global context, but i'm thinking that this cannot be changed. --- Ciao Romano

 [22/25] from: rotenca:telvia:it at: 18-Nov-2002 22:40


Hi Gabriele
> I agree with Ladislav.
Gabriele, you bypass Load for this, i was speaking of Load. And my observation is still valid, also a set-path can be used like a path by the interpreter if it find a function along the path. Now i'm thinking that the problem is all in function refinement, see my previous message.
> In particular: > >> f: func [/ref] [1]
<<quoted lines omitted: 10>>
> >> do reduce [p] > == 1
This is what i point: no set action at all, the interpreter does not care about the fact the that path is a set-path!
> >> p: to set-path! [f ref] > == f/ref: > >> do reduce [p] > == 1 > which shows that REBOL is just being very permissive for functions > with refinements.
At least.
> I think that for both set-path! and path!, first of all REBOL > determines the value of the first word. Then, it "decodes" the
<<quoted lines omitted: 3>>
> code handling functions, that simply does not "know" about > set-path!s and so behaves like it was a path!.
Yes you are right and this is what i want to point. I did not want to say that set-path does not exists in absolute, but that in some situations it is like a path. I could make an example: a block which, if at some point contains the word list!, start to behaviour like a list!. Only in this sense i said that it is not a true datatype!.
> RPT> Often I'm asking myself: what are advantages of refinements in
functions?
> Economy of expression. Without refinements, using functions like > OPEN would require a lot of arguments.
open: func [file type [integer!]][ if type and 1 [ ;direct] if type and 2 [ ;no-wait] if type and 4 [ ;binary] or open: func [file type [block!]][ if find type 'direct [ ;direct] if find type 'no-wait [ ;no-wait] if find type 'binary [ ;binary]
> Also, one could not extend > functions retaining compatibility like it was done with MOLD (/ALL > refinement) or LOAD (/LIBRARY refinement) etc.
You are right. Also because any-type! cannot help for backward compatibility. --- Ciao Romano

 [23/25] from: g:santilli:tiscalinet:it at: 20-Nov-2002 12:58


Hi Romano, On Monday, November 18, 2002, 10:40:21 PM, you wrote: RPT> Yes you are right and this is what i want to point. I did not want to say that RPT> set-path does not exists in absolute, but that in some situations it is like a RPT> path. I could make an example: a block which, if at some point contains the RPT> word list!, start to behaviour like a list!. Only in this sense i said that it RPT> is not a true datatype!. One could argue that all any-block! types actually share the same implementation internally. This doesn't make them one datatype; parens and blocks differ only in the delimitator, and paths and set-paths differ only in that set-path! ends with a colon. (REBOL is so small because most datatypes share the same implementation...) RPT> or RPT> open: func [file type [block!]][ RPT> if find type 'direct [ ;direct] RPT> if find type 'no-wait [ ;no-wait] RPT> if find type 'binary [ ;binary] Basically, any function that requires a lot of optional arguments would require its own dialect. To make things cleaner, Carl thought of refinements as a common way that can be used by all the functions. Of course, we miss a clean way to propagate refinements, etc. However, I don't think that your proposal of having: f: func [] [[[1]]] f/1 ; == [1] f/1/1 ; == 1 makes really sense out of this simple example. I would find the following really unintuitive: f: func [a b c] [reduce [a b c]] f/1 1 2 3 ; == 1 f/2 1 2 3 ; == 2 ; etc. (Imagine it when you have less trivial arguments, as in a long expression.) I would much prefer: (f 1 2 3)/1 (f 1 2 3)/2 etc. Anyway, the path notation is just a shortcut notation. When you can't use paths, you can use PICK and POKE, so there's no real limitation. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [24/25] from: rotenca:telvia:it at: 20-Nov-2002 19:33


Hi Gabriele
> makes really sense out of this simple example. I would find the > following really unintuitive: > > f: func [a b c] [reduce [a b c]] > > f/1 1 2 3 ; == 1 > f/2 1 2 3 ; == 2 > ; etc.
You find it unintuitive because you think at refinement as /word. If a: [b 1] a/b means: 1) evaluate 'a 2a) if a results in a block, select it with the word 'b 2b) if a results in a object, get in it the word 'b I should like that this means the exactly same: a: func [][[b 1]] a/b 1) evaluate 'a (which, because it is a function, means "execute the body and return the last value") 2a) if a results in a block, select it with the word 'b 2b) if a results in a object, get in it the word 'b Instead, because function refinements are = path divisor (only for a choice) that expression means all another thing: "evaluate the function and pass /b as a refinement to it." and before evaluating 'a i can't know what is the right interpretation! Functions are first class?
> (Imagine it when you have less trivial arguments, as in a long > expression.) I would much prefer: > > (f 1 2 3)/1 > (f 1 2 3)/2
this is indipendent from the previous: can be considered an extension of the previous to pass arguments to a function (but could be used for compatibility: a/b ;old interpretation (a)/b ; my interpretation (a/d 1)/b ; my interpretation + function refinement + arg
> Anyway, the path notation is just a shortcut notation. When you > can't use paths, you can use PICK and POKE, so there's no real > limitation.
yes, you must only decide between 1) Pick, Select, Get In, call a function 2) Poke, Change Find, Set In, call a function Not so simple... --- Ciao Romano

 [25/25] from: g:santilli:tiscalinet:it at: 20-Nov-2002 19:53


Hi Romano, On Wednesday, November 20, 2002, 7:33:46 PM, you wrote: RPT> You find it unintuitive because you think at refinement as /word. I find it unintuitive in the case that the function has arguments. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted