Also this approach uses more memory.  At least a byte per pointer and maybe 
more with padding.  In most cases like this you would prefer to use a vtable 
instead of tags to reduce the memory footprint.

Eric

On Mar 13, 2014, at 1:17 PM, Eric Summers <eric.summ...@me.com> wrote:

> Matthieu,
> 
> I tried to model something similar this way.  Sometimes the extra pattern 
> matching gets tedious with this approach.  You also end up with a lot of 
> constructors with similar names.  I also found myself  writing a lot of 
> trivial function wrappers around constructors.  Of course there are benefits 
> to a non-extensible system like this.  For instance, you can tell if you have 
> addressed every case in a match statement.
> 
> Someone on IRC mentioned that a feature similar to Haskell pattern synonyms 
> may make it less awkward to use these enum wrappers.
> 
> Eric
> 
> On Mar 13, 2014, at 12:56 PM, Matthieu Monrocq <matthieu.monr...@gmail.com> 
> wrote:
> 
>> And of course I forgot to reply to the list at large... sorry :x
>>  
>> -- Matthieu
>> 
>> 
>> On Wed, Mar 12, 2014 at 8:48 PM, Matthieu Monrocq 
>> <matthieu.monr...@gmail.com> wrote:
>> 
>> 
>> 
>> On Tue, Mar 11, 2014 at 10:18 PM, Patrick Walton <pcwal...@mozilla.com> 
>> wrote:
>> On 3/11/14 2:15 PM, Maciej Piechotka wrote:
>> Could you elaborate on DOM? I saw it referred a few times but I haven't
>> seen any details. I wrote simple bindings to libxml2 dom
>> (https://github.com/uzytkownik/xml-rs - warning - I wrote it while I was
>> learning ruby) and I don't think there was a problem of OO - main
>> problem was mapping libxml memory management and rust's one [I gave up
>> with namespaces but with native rust dom implementation it would be
>> possible to solve in nicer way]. Of course - I might've been at too
>> early stage.
>> 
>> You need:
>> 
>> 1. One-word pointers to each DOM node, not two. Every DOM node has 5 
>> pointers inside (parent, first child, last child, next sibling, previous 
>> sibling). Using trait objects would 10 words, not 5 words, and would 
>> constitute a large memory regression over current browser engines.
>> 
>> 2. Access to fields common to every instance of a trait without virtual 
>> dispatch. Otherwise the browser will be at a significant performance 
>> disadvantage relative to other engines.
>> 
>> 3. Downcasting and upcasting.
>> 
>> 4. Inheritance with the prefix property, to allow for (2).
>> 
>> If anyone has alternative proposals that handle these constraints that are 
>> more orthogonal and are pleasant to use, then I'm happy to hear them. I'm 
>> just saying that dismissing the feature out of hand is not productive.
>> 
>> 
>> Patrick
>> 
>> 
>> Please excuse me, I need some kind of visualization here, so I concocted a 
>> simple tree:
>> 
>> // So, in pseudo C++, let's imagine a DOM tree
>> struct Element { Element *parent, *prevSib, *nextSib, *firstChild, 
>> *lastChild; uint leftPos, topPos, height, width; bool hidden; };
>> struct Block: Element { BlockProperties blockP; }; struct Div: Block {};
>> struct Inline: Element { InlineProperties inlineP; }; struct Span: Inline {};
>> 
>> 
>> Now, I'll be basically mimicking the way LLVM structures its AST, since the 
>> LLVM AST achieves dynamic casting without RTTI. Note that this has a very 
>> specific downside: the hierarchy is NOT extensible.
>> 
>> // And now in Rust (excuse my poor syntax/errors)
>> enum ElementChild<'r> { ChildBlock(&'r Block), ChildInline(&'r Inline) }
>> 
>> struct Element {
>>     child: Option<&'self ElementChild<'self>>;
>>     parent: &'self Element;
>>     prevSib, nextSib, firstChild, lastChild: Option<&'self Element>;
>>     leftPos, topPos, height, width: uint;
>>     hidden: bool;
>> }
>> 
>> 
>> enum BlockChild<'r> { ChildDiv(&'r Div) }
>> 
>> struct Block {
>>     elementBase: Element;
>>     child: Option<&'self BlockChild<'self>>;
>>     blockP: BlockProperties;
>> }
>> 
>> struct Div { blockBase: Block; }
>> 
>> 
>> enum InlineChild<'r> { ChildSpan(&'r Span) }
>> 
>> struct Inline {
>>     elementBase: Element;
>>     child: Option<&'self InlineChild<'self>>;
>>     inlineP: InlineProperties;
>> }
>> 
>> struct Span { inlineBase: Inline; }
>> 
>> 
>> Let us review our objectives:
>> 
>> (1) One word to each DOM element: check => Option<&'r Element>
>> 
>> (2) Direct access to a field, without indirection: check => 
>> span.inlineBase.elementBase.hidden
>> 
>> (3) Downcast and upcasting: check => downcast is done by matching: 
>> match(element.child) { ChildBlock(&'r block) => /* act on block */, 
>> ChildInline(&'r inline) => /* act on inline */); upcast is just accessing 
>> the "base" field.
>> 
>> (4) Inheritance with the prefix property => not necessary, (2) is already 
>> satisfied.
>> 
>> 
>> Note on (3): multiple bases are allowed easily, it's one field per base.
>> 
>> 
>> In order to reduce the foot-print; avoiding having a "child" field at each 
>> level of the hierarchy might be beneficial. In this case, only the final 
>> classes are considered in ElementChild
>> 
>> enum ElementChild<'r> { ChildDiv(&'r Div), ChildSpan(&'r Span) }
>> 
>> And then downcasting to &'r Block is achieved by:
>> 
>> match(element.final) { ChildDiv(&'r div) => Some(&'r div.blockBase), _ => 
>> None }
>> 
>> 
>> I would note that this does not make use of traits at all; the analysis is 
>> only based on Patrick's list of objectives which I guess is incomplete and I 
>> was lacking a realistic example so it might not address the full scope of 
>> the problem...
>> 
>> ... still, for CLOSED hierarchies, the use of traits should not be 
>> necessary, although it might be very convenient.
>> 
>> -- Matthieu.
>>  
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
>> 
>> 
>> _______________________________________________
>> Rust-dev mailing list
>> Rust-dev@mozilla.org
>> https://mail.mozilla.org/listinfo/rust-dev
> 
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to