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

When is none not none?

 [1/8] from: jonkelly:fastmail:fm at: 26-Jul-2007 23:51


Hi, newbie alert. I'm confused. I managed to finally get the attached script (t3.r) to work as I expect. It's a binary tree insertion function. BUT, if you change all the empty blocks for none (t4.r), (which was how I tried to start out) it barfs, saying none is a word. I was trying to do a purely function version but that made my head hurt. Jonathan. -- Binary/unsupported file stripped by Ecartis -- -- Type: text/x-rebol -- File: t3.r -- Binary/unsupported file stripped by Ecartis -- -- Type: text/x-rebol -- File: t4.r

 [2/8] from: jonkelly:fastmail:fm at: 26-Jul-2007 23:55


How annoying is that! :/ This is the working version ... REBOL [ Title: "Binary tree insertion with terminals = []" Date: 2-Jul-2007 File: %t2.r Author: "Jonathan Kelly" Version: 0.0.1 ] add: func [ blk val ] [ print [ "add" blk type? blk blk = [] val] either blk = [] [ print "at A" compose [ (val) [] [] ] ] [ either blk/1 = val [ print "at equals" blk ] [ either val > blk/1 [ print "at greater" poke blk 3 (add blk/3 val) ] [ print "at less" poke blk 2 (add blk/2 val) ] blk ] ] ] tt: add [] "c" prin [ "tt is " ] probe tt print [] tt: add tt "b" prin [ "tt is " ] probe tt print [] tt: add tt "e" prin [ "tt is " ] probe tt print [] tt: add tt "d" prin [ "tt is " ] probe tt print []

 [3/8] from: jonkelly:fastmail:fm at: 26-Jul-2007 23:56


and this is the not working version REBOL [ Title: "Binary tree insertion with terminals = none" Date: 2-Jul-2007 File: %t2.r Author: "Jonathan Kelly" Version: 0.0.1 ] add: func [ blk val ] [ print [ "add" blk type? blk blk = none val] either blk = none [ print "at A" compose [ (val) none none ] ] [ either blk/1 = val [ print "at equals" blk ] [ either val > blk/1 [ print "at greater" poke blk 3 (add blk/3 val) ] [ print "at less" poke blk 2 (add blk/2 val) ] blk ] ] ] tt: add none "c" prin [ "tt is " ] probe tt print [] tt: add tt "b" prin [ "tt is " ] probe tt print [] tt: add tt "e" prin [ "tt is " ] probe tt print [] tt: add tt "d" prin [ "tt is " ] probe tt print []

 [4/8] from: jonkelly:fastmail:fm at: 27-Jul-2007 0:03


Damn. Why is it you only see these things seconds after you've posted it to the whole world?? :)
> compose [ (val) none none ]
should be compose [ (val) (none) (none) ] and it works. So none is not none when it's the word and not the value.

 [5/8] from: henrik:webz:dk at: 26-Jul-2007 16:31


On 26/07/2007, at 16:03, Jonathan Kelly wrote:
> compose [ (val) (none) (none) ]
Alternatively: reduce [val none none] And of curiosity, you get none back as a word, which produces an error: reduce [val 'none 'none] -- Regards, Henrik Mikael Kristensen

 [6/8] from: moliad::gmail::com at: 26-Jul-2007 11:47


Hi Jonathan, Welcome to Rebol, hope you have a blast. what you are experiencing is a subtlety of static run-time loading and binding. some functions evaluate values and others do not. in this case, compose loads a block and leaves everything within AS-IS. so since the interpreter has to put the none somewhere as something, it stays a word, gets bound to the global definition of none, but isn't evaluated, so its not yet a none *value*. I have had the same (I thought "strange", at the time) problems with the true and false values, which have no lexical form which allows them to be explicitly cast as a datatype. since many of us have lived through this exact issue, I can already warn you about loading data files. nested blocks, do not recursively get evaluated by load, so you can end up with this same problem when saving out blocks and objects and stuff. a good way to identify this is to use the mold/all function which *serializes* the data. in fact, I have replaced probe in my setup so that it molds/all in order to clearly identify datatypes. ex of mold/all usage:
>>a: mold/all compose [none (none)] >>probe a
== "[none #[none]]" this allows you to realize without chance of a subtle error, just what is going on. Note that mold returns a string. then whenever you do a load of that string, you know that it will return exactly, value-wise, like it was. HTH ! -MAx On 7/26/07, Henrik Mikael Kristensen <henrik-webz.dk> wrote:

 [7/8] from: lmecir::mbox::vol::cz at: 30-Jul-2007 12:01


Maxim Olivier-Adlhoch napsal(a):
> Hi Jonathan, > > Welcome to Rebol, hope you have a blast. > > what you are experiencing is a subtlety of static run-time loading and > binding.
Binding is slightly off-topic in this case, "static run-time" is a contradictio in adjecto.
> some functions evaluate values and others do not. in this case, > compose loads a block and leaves everything within AS-IS.
Wrong. The interpreter loads the block before evaluating the expression. Compose does not. (Do you want a proof?)
> so since the > interpreter has to put the none somewhere as something, it stays a word,
<<quoted lines omitted: 3>>
> true and false values, which have no lexical form which allows them to be > explicitly cast as a datatype.
Wrong. Here are the lexical forms of some Rebol values popularly thought not having lexical form: values: [#[unset!] #[none] #[false] #[true]] As opposed to that, when writing: words: [unset! none false true] the Words block will just contain words.
> since many of us have lived through this exact issue, I can already warn you > about loading data files. > nested blocks, do not recursively get evaluated > by load, so you can end up with this same problem when saving out blocks and > objects and stuff. >
Confusing. Nested blocks are processed by Load in exactly the same way it processes the top-level block. The Load function does just what it is supposed to. Example: code: load "none [true false]" produces a block containing one word and a nested block containing two words. This means, that Load evaluates neither the nested nor the top-level block.
> a good way to identify this is to use the mold/all function which > *serializes* the data. in fact, I have replaced probe in my setup so that > it molds/all in order to clearly identify datatypes.
This is my Probe version: probe: func [ {Prints molded Value. Returns Value.} value [any-type!] ] [ print case [ not value? 'value ["#[unset!]"] error? :value [rejoin ["#[error!" mold/all copy skip second disarm :value 2 "]"]] true [mold/all :value] ] return get/any 'value ] example: probe compose [none #[none] (none) false #[false] (false) true #[true] (true)] -L

 [8/8] from: moliad::gmail::com at: 30-Jul-2007 15:00


On 7/30/07, Ladislav Mecir <lmecir-mbox.vol.cz> wrote:
> Maxim Olivier-Adlhoch napsal(a): > > Hi Jonathan,
<<quoted lines omitted: 5>>
> Binding is slightly off-topic in this case, "static run-time" is a > contradictio in adjecto.
hum... I didn't say static dynamic. the binding is static (its not a scope) and is applied at run time, manually (as words are encountered during execution of your application which is usually at load time), but can also be while building objects, using bind, etc.
> some functions evaluate values and others do not. in this case, > > compose loads a block and leaves everything within AS-IS. > Wrong. The interpreter loads the block before evaluating the expression. > Compose does not. (Do you want a proof?)
yes the interpreter itself does the loading. but the nuance was in the fact that some functions need blocks which are bound and others dont care... I should have been a bit more volubile I guess.. in this case compose does not evaluate anything except parens.
> > so since the > > interpreter has to put the none somewhere as something, it stays a word,
<<quoted lines omitted: 9>>
> Wrong. Here are the lexical forms of some Rebol values popularly thought > not having lexical form:
not talking about serialized form. direct unserialized notation an extension of what I was saying :-) , so we agree, if you want to be sure the interpreter knows what none is.. use #[none] I use it often in my code. for the recursive block loading, its a more complex example which will illustrate what I meant, but I have no time right now :-( it might be within a specific datatype (like object!), but at some point, one needs to run 'DO on top of 'LOAD, whereas saving in serialised form alleviates this dangerous step. thanks for adding precision to my words ;-) -MAx

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