Hey Linas!

All your points about “Engineering" vs. "Knowing what you are Building" are 
right on.  Rust is a systems-level language that you bring in when you have a 
pretty good idea about what you are building and you care about execution speed 
and long-term maintainability.  It’s not a good platform for experimentation.  
That said, I can experiment faster in Rust than I ever could in C++.  And I 
never ever lose days to debugging memory stompers or data races.  Which is 
pretty huge for me as those cost me a lot of momentum on past projects.

So, what I wrote was not to suggest Rust is a bad fit for Hyperon’s Atomspace.  
Just that the default Box<dyn Trait> approach typically used for polymorphism 
in Rust may need to be extended with some additional customization (implemented 
with `unsafe`) to make it do what you want.  Still a little bit of unsafe in 
Rust is better than everything being unsafe in C++.

Rust is an awesome language for a whole host of reasons from the performance to 
the memory safety to the well-thought-out std library.  (Almost) every 
limitation in the language is there for a good reason - it’s just that those 
reasons might not entirely apply to our use case and we might have made 
different choices if we were designing a perfect language to implement 
something like Atomspace.

> On Dec 29, 2021, at 6:52 PM, Linas Vepstas <[email protected]> wrote:
> 
> On Tue, Dec 28, 2021 at 8:11 PM Luke Peterson <[email protected]> wrote:
> 
>> I concluded that the Rust trait system and dyn dispatch mechanism was a bad 
>> fit - at least without quite a bit of additional plumbing and glue.  Things 
>> it needs to do in order to perform the compile-time monomorphization 
>> prohibit the kind of fast-and-loose polymorphism that you need.
> 
> Speaking of polymorphism, I've discovered that OCaML has a similar set
> of issues. My zeroth impression was that it's a modern typed
> functional language with high performance. Should be a good fit for
> the AtomSpace, right?
> 
> Nope. After fiddling with it for a few weeks, I "discovered" the OCaml
> type system was static, compile-time typed, and there are no
> provisions for run-time type-casting/polymorphism. That means, for
> example, if I define a type "Atom" at the beginning, and then, minutes
> or hours later add something like ProteinNode, there's no way to pass
> this to something expecting an Atom; conversely, given an Atom,
> there's no way to discover it's actually a ProteinNode.  (no
> polymorphic lists, either)

I don’t know OCaml at all but Rust does have a Polymorphism mechanism, via the 
`dyn` keyword.  This basically tells the compiler to build a vtable.  It works 
well most of the time.

The main annoyance with it is that it’s incompatible with generics - again this 
makes sense because a generic monomorphizes into many different 
implementations, and you wouldn’t want the number of vtable entries to explode. 
(https://rust-lang.github.io/rfcs/0255-object-safety.html 
<https://rust-lang.github.io/rfcs/0255-object-safety.html>)  But what it means 
is that you often have to do type erasure and create dynamic wrappers manually. 
 For example (https://github.com/dtolnay/dyn-clone 
<https://github.com/dtolnay/dyn-clone>)  Runtime-performance-wise, you’re no 
worse off than if you were working in a language that did the indirection 
behind the scenes - but sometimes the extra keystrokes are annoying.

As far as getting from a `dyn Trait` object back to the concrete object you 
started with, Rust offers the `Any` trait. 
(https://doc.rust-lang.org/std/any/index.html 
<https://doc.rust-lang.org/std/any/index.html>) which works in the majority of 
cases.  Unfortunately it’s limited to objects that don’t reference other 
objects ('static lifetimes), because the lifetime tracking is resolved at 
compile time so you couldn’t safely guarantee a reference didn’t outlive a 
referent.  So if you know this is ok in your situation, you’ll need to use 
unsafe to tell the compiler to let you do it.

These kind of limitations make a lot of sense when considering the overall 
design goals of Rust, but aren’t ideal for implementing an executable node 
graph.  Luckily you can use unsafe in a few judicious places and make make Rust 
do what you want.

> 
> Of course, this could be made to work with a lot of extra "plumbing
> and glue", but adding that plumbing defeats the whole point of having
> the OCaML type system, which was (*) type safety (*) compile-time
> optimizations.  More about that here:
> https://github.com/opencog/atomspace/tree/master/opencog/ocaml
> 
> -----------------
> Reading about Rust, I see "traits" as an important language feature.
> Reading about traits says that both Haskel and OCaml can support them
> ("easily"??)  I don't know OCaml well enough to figure this out, or if
> this would be a good match for the atomspace type system.  I'm utterly
> lost as to vsbogd's issues, or what alice & quinedot wrote.
> 
> Which leads to some other off-hand comments: the reason the atomspace
> keeps getting smaller and simpler is so that .. well, complexity and
> over-engineering is the enemy. One should always try to keep things as
> simple as possible. This helps avoid hard-to-debug problems, and it
> also helps performance. (Those paying attention might have noticed
> some large parts of the atomspace were nuked to oblivion in the last 6
> months.  It's gotten smaller and simpler... again.)
> 
> One humble suggestion for hyperon: instead of trying to reinvent the
> atomspace, you might have more luck and less expended effort by just
> ... using the atomspace as-is, and layering what you need on top.
> Don't create headaches where they don't need to exist.  Focus on doing
> the experiments that you need to do, get them to work right. After
> they work, after you get good results, then and only then start
> thinking about what kind of infrastructure you need. Don't put the
> cart before the horse. Don't over-engineer.
> 
> Everyone here has observed that I do most of my work in scheme.
> There's a reason for this: when coding in scheme, one never-ever runs
> into problems where the language/compiler is trying to stop you from
> doing "the obvious thing" (as OCAML is doing, and as Rust is doing,
> apparently.)  This flexibility of being able to do anything you want,
> anything you feel  like, without having to stop to ask questions on
> stackexchange, is one of the huge benefits of scheme/lisp.
> 
> Socially, though, it is a curse: because everything is so easy,
> programmers never feel much of an urge to standardize anything,
> instead working happily with their home-grown solutions.  There is a
> worthwhile essay about this to read and ponder:
> 
> http://www.winestockwebdesign.com/Essays/Lisp_Curse.html
> 
> I think the above essay explains vsbogd's problem with Rust. (about 5
> paragraphs down.)
> 
> Since I'm on the topic: perhaps my biggest #1 greatest "discovery"
> about the atomspace is that it would be really really really nice to
> have a vector (matrix, tensor) API to it. To be able to say "here's a
> vector of Atoms". Because, well, vectors are really really useful. I
> implemented one, its here:
> https://github.com/opencog/atomspace/tree/master/opencog/matrix
> Unfortunately, it is in ... scheme, so the pythonistas and rustaceans
> are out of luck. Someone should recreate this API in C++ (and thus get
> R and python bindings "for free") ...
> 
> Why the heck am I talking about this? It's an example of a
> "discovery".  I didn't start with a profound theoretical insight or
> fundamentalist proclamation.  I started with a tiny collection of
> small-time utilities to make writing code easier. Over time, it
> evolved and got more sophisticated, as the actual needs became clear.
> Now that the shape of the thing is clear, and the need for it is
> fairly obvious, one can go back and "harden" the code, formalize it,
> rewrite it, tune it, optimize it.
> 
> Put the horse before the cart: Let experiments and quick-n-dirty
> attempts be the horse. They'll pull the cart of infrastructure, the
> code base, in the direction you want to go in.  Find what works,
> first. Make it industrial-strength second.
> 
> -- Linas
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "opencog" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/opencog/CAHrUA34VC1a46TUFZ_zzVpOtJUUZgZOM4YebidmaumjcWdzR7w%40mail.gmail.com.

-- 
You received this message because you are subscribed to the Google Groups 
"opencog" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/opencog/902613E8-FF1A-4713-AAC3-35F0B94901CA%40gmail.com.

Reply via email to