mkristian has quit [Read error: Operation timed out]
zekefast has joined #rom-rb
mbj has quit [Quit: leaving]
zekefast has quit [Client Quit]
snusnu1 has joined #rom-rb
snusnu1 has quit [Quit: Leaving.]
irclogger__ has joined #rom-rb
bf4 has joined #rom-rb
irclogger__ has quit [Remote host closed the connection]
irclogger__ has joined #rom-rb
snusnu has joined #rom-rb
irclogger__ has quit [Remote host closed the connection]
irclogger__ has joined #rom-rb
irclogger__ has quit [Remote host closed the connection]
irclogger__ has joined #rom-rb
irclogger__ has quit [Remote host closed the connection]
irclogger__ has joined #rom-rb
dkubb has joined #rom-rb
<dkubb>
good morning
<elskwid>
Howdy dkubb
zekefast has joined #rom-rb
mkristian_ has quit [Ping timeout: 260 seconds]
<dkubb>
elskwid: how's things going with virtus? anything blocking you?
<elskwid>
dkubb: Mostly time. I have had a very busy couple of weeks. I plan to get more done on the docs today (I'm almost finished) and get that `with` PR merged in.
<elskwid>
dkubb: In a strange twist of fate, a local company wants to do some work with me and I have been helping them with their legal docs. (They were old and horribly written).
<elskwid>
Very weird to say "hrm, I need to send these to my lawyer." and "we'll come up with an NDA for you" ha ha
<dkubb>
legal docs? as in licenses or something else?
<elskwid>
NDA and confidentiality
<dkubb>
ahh ok
<dkubb>
the funny thing is that everytime I've ever signed an NDA it turns out there was really no "secret sauce" to protect
<dkubb>
I suppose companies like google, with it's ranking algorithm, might qualify for it.. but usually it means that the company just doesn't have the awareness that what they are doing is common practice, or at least common knowledge in a specific niche
<dkubb>
that's just ime of course
<snusnu>
hey dkubb
<snusnu>
dkubb: i'm thinking that i will have a working spike for a rom-mapper working on top of ducktrap by the end of the week
<dkubb>
snusnu: I've finished mutation testing axiom, and am about to do a refactoring on how methods are added to specific types of objects
<dkubb>
snusnu: ahh I see, so the same ROM mapping code
<snusnu>
yeah, i'm planning to use it inside our app, to get a feel how it goes .. we'll see, but eventually, i guess not much will need to change for it to be rom-mapper proper
<dkubb>
snusnu: the fetch_key stuff doesn't rely on a Hash does it? It only relies on the object responding to #[] ?
<snusnu>
dkubb: yeah it does iirc, and if it doesn't, it should
<dkubb>
cool
<snusnu>
dkubb: but i'd doubt that mbj tied it to Hash the type
<dkubb>
yeah I doubt he did too
<dkubb>
so once you generate this, it will effectively make the dump and load stuff for you
<snusnu>
exactly
<dkubb>
nice!
jgaskins has quit [Quit: This computer has gone to sleep]
<snusnu>
i'm currently struggling with EC/EV .. since they basically need the "primitive" ducktraps defined already
<snusnu>
so when you look at a wrap :address, Address mapping definition … it would need to look up the ducktrap generated for Address in some registry
<snusnu>
i guess we'll also run into (already known) circular declaration issues (like virtus did and DM1 too)
<snusnu>
but for now, that's kinda out of scope for me
<dkubb>
yeah, it's funny how the same problem keeps cropping up
<snusnu>
heh yeah
<dkubb>
I'm not convinced that it's been solved yet
<snusnu>
me neither
<snusnu>
but strict immutability gets us closer
<snusnu>
as systems are designed differently
<dkubb>
what you need to do is break the chain, and add a lazy placeholder for the value you don't know yet
<snusnu>
it gives a fresh perspective to look at the problem
<dkubb>
when you finalize you can replace the placeholder with something real
<snusnu>
yeah, i might have to .. but we'll see how far it goes (in practice) .. without supporting it at all
<snusnu>
i have this hunch, that *I* will rarely need stuff like PersonWithTasks *and* TaskWithPerson
<snusnu>
i'm thinking one can "work around" those circular definitions, with a different style of domain entities
<snusnu>
but i'll see
<dkubb>
yeah, better to defer doing thatr work as long as you can
<snusnu>
right
<snusnu>
btw, wdyt about the #rename DSL method? the motivation behind it, was to *not* clutter #map with an options param .. because my thinking is, that those options will eventually be "reserved" for constraint'ish things
<snusnu>
altho otoh, i'm not yet entirely sure if the mapper would be the right place for that anyway, in fact, i don't think so
<snusnu>
real (serializable) constraints should be defined on the schema .. and validations should be defined in external validators (vanguard)
<snusnu>
still, it feels somewhat odd to have an options param, with exactly one acceptable options (say, :field)
<snusnu>
so #rename seems to fit better
<dkubb>
it's hard because the name "map" seems like it could be what I would expect to map one field to another.. but it's also not bad to have an explicit name either
<snusnu>
yeah, we'll see .. in any case, that kind of mapping would most likely occur only when connecting to legacy databases
<snusnu>
i somehow think that i'd favor to have the renaming in one place .. not scattered around various "property" definitions
<dkubb>
snusnu: I think the schema could do the renaming
<snusnu>
that might very well be a good idea too, yeah
<dkubb>
snusnu: keep the mapping layer simple, and do renaming in the schema one time.. for now anyway
<snusnu>
now that you say it, i even think that we actually decided to do it like that quite a while ago already ;)
<dkubb>
snusnu: if we find ourselves wanting to use different attribute names all the time from different mappers to the same relations, then we can change it
<dkubb>
but for now we should do the least amount of work possible
<snusnu>
yup, agreed
<snusnu>
btw, i couldn't help but notice that this mapper i'm writing, is in some way an "external virtus"
<snusnu>
if you know what i mean ...
<dkubb>
heh
<dkubb>
yeah, it seems to come close
<snusnu>
which is nice imo, since i always had the feeling, that "cluttering" the domain entities with typing related DSL, feels a little weird in ruby .. even tho i'm fully aware that virtus *instances* know nothing about typing
<snusnu>
otoh, it does a lot less than virtus does obviously
<snusnu>
which is nice too
<snusnu>
and it is *completely* decoupled from rom actually, it needn't know about relation stuff *at all* .. give it an array of (nested) hashes, and you're all set
<snusnu>
in fact, it's simply another DSL for ducktrap, tailored to a specific usecase (mapping)
<dkubb>
I like the idea of rom working with an Array of Hashes
<dkubb>
it will make testing really nice
<dkubb>
there's no need for people to duplicate testing of axiom since it's better tested than they'd ever be able to do in an app
<snusnu>
yeah agreed
<snusnu>
i also like how it constantly "pushes away / defers" the problem of relationship definition .. or well, solving parts of it that aren't strictly related, somewhere else
<snusnu>
relationships will eventually boil down to what they are .. FK constraint definitions on the schema
jgaskins has joined #rom-rb
snusnu has quit [Quit: Leaving.]
snusnu has joined #rom-rb
<jgaskins>
hey dkubb
<dkubb>
jgaskins: hey, how's it going?
<jgaskins>
pretty good. finally made it to irc. :-)
mbj has joined #rom-rb
snusnu has quit [Quit: Leaving.]
<dkubb>
hehe
<mbj>
hi
<dkubb>
almost all the good discussion happens in irc
<dkubb>
mbj: hi
<mbj>
dkubb: Reading backlog.
<mbj>
dkubb: BTW I have an fantastic ducktrap / vanguard / predicates (and maybe also axiom-logic) refactoring in the pipeline.
<mbj>
I have an AST based transformation algebra lib written in flight back to europe.
<mbj>
It allows to create an evaluation tree that does NOT track and NOT creates new objects.
<mbj>
And one doing all the stuff with history.
<mbj>
As it is AST based it allows to define the DSL totally independant from the evlautor builder.
<mbj>
Also this thing will power my xspec framework. And the mutant filters ;)
<mbj>
invariants are nothing more like predicates.
<mbj>
The buildin evaluation history will allow me to write good reporters.
mkristian_ has joined #rom-rb
<dkubb>
mbj: one thing I need with axiom is to know the axiom return type of expressions, so I know what kinds of methods I can call on an expression
<mbj>
dkubb: I think I can add this.
<mbj>
Already though about this.
snusnu has joined #rom-rb
<mbj>
dkubb: I think types can be added in special nodes.
<mbj>
dkubb: for some nodes types are obvious, for example nodes that are predicates.
<dkubb>
mbj: for example, the expression attribute.length returns a type of Axiom::Types::Integer, and would be able to use any integer type method so that I could write stuff like: attribute.length.gte(4)
<mbj>
Got it.
<dkubb>
mbj: yeah, but even those would return an Axiom::Types::Boolean
<dkubb>
mbj: which would allow methods like .and or .or
<mbj>
Yeah.
<mbj>
I'll start with non typed, and add types later.
<dkubb>
mbj: I'm going to be refactoring axiom internals on how methods are associated with types
<mbj>
Or sooner.
<mbj>
But I like the idea.
<mbj>
I'll do this stuff with axiom in mind. But for now it would be totally okay for me to unite ducktrap / vanguard / mutant / xspec internals.
<dkubb>
mbj: right now they're basically mixed into the objects that have types, like Axiom::Relation, Axiom::Attribute::String, etc.. what I want to do is say "these methods are available to any object that returns an Axiom::Types::String"
<dkubb>
and then figure out some way to mix those into the objects without doing any method-missing magic
<dkubb>
it shouldn't be too difficult. I
<mbj>
+1
<dkubb>
I'll likely have a module for each type and then mix that into the concrete objects, and from there on any methods mixed into those modules will be propagated to the correct concrete object
<dkubb>
a few functions like sum return a different type depending on the inputs, so I'll probably have to subclass it once per type
<mbj>
I like this idea.
snusnu has quit [Quit: Leaving.]
<dkubb>
yeah, it'll make it so adding new operators is much easier too
<dkubb>
you'll only have to think about the type you need to attach to, and it'll be propagated to all the objects that return it
snusnu has joined #rom-rb
<mbj>
dkubb: +1
zekefast has quit [Quit: Leaving.]
<dkubb>
solnic's not going to be around much, he and his wife had a baby boy yesterday
<mbj>
dkubb: Yeah saw the photo. Looks very distracting ;)
<mbj>
dkubb: In the positive way ;)
<dkubb>
oh yeah.. that's one of the best times
<dkubb>
mbj: one class of mutation I'd like to try to identify is weaker to stronger constructs. we've done with send -> public_send in the past, and it helped me find a few places where I really didn't need send.. I was only calling public methods
<dkubb>
I'm sure there are lots of them out there
<dkubb>
snusnu: for schema renames, I wonder if something like this could work: schema[:users] = schema[:users].rename(full_name: :name)
<dkubb>
snusnu: not necessarily the syntax, which I don't know if it's supported, just the idea.. re-assigning the renamed relation back to the "slot" where the original was
<dkubb>
snusnu: we could also use this to apply things like like constraints, eg: schema[:active_users] = schema[:users].restrict(active: true)
<snusnu>
dkubb: hmm, not too sure about that, at least, well, not this particular syntax, or rather, the idea of *re*assigning back .. i want the schema to be immutable
<mbj>
dkubb: if you do symetric mutations you run into problems.
<mbj>
dkubb: public_send => send, and send => public_send is very uneasy to kill.
<dkubb>
mbj: yeah, we always have to go from weaker to stronger
<snusnu>
dkubb: if it were to return a new, different schema, i'm all for it tho
<snusnu>
also, hey mbj
<snusnu>
back home?
<mbj>
snusnu: hey ;)
<mbj>
snusnu: Yeah
<mbj>
But a littlebit sick.
<snusnu>
damnit
<mbj>
Climate difference is huge.
<snusnu>
heh
<mbj>
Actually more sick than a littlebit.
<snusnu>
:/
<dkubb>
snusnu: yeah, I could see it doing something like that. I'll think about the interface a bit more
<dkubb>
snusnu: I wouldn't mind so much if it was mutable as long as it could be finalized. it'd be more important that it be frozen at runtime than if it were frozen during compile/build time
<snusnu>
dkubb: hmm .. tbh, i don't like finalization
<snusnu>
if we can go without, we should avoid it
<snusnu>
if we can't find a feasible way to do some *specific* problem without finalization, we can still add it
<snusnu>
i found that oftentimes, "intermediate" representations of some concepts, do what finalization does .. only, it gives "intermediate state" (state, while building up the system) .. a dedicated name
<snusnu>
so, with every step, you create a new representation of a system .. closer to being "complete" .. where with finalization, you're kinda "lazy" and don't assign dedicated names to various intermediate states
jgaskins has quit [Quit: This computer has gone to sleep]
<snusnu>
to that respect, my recent namings oftentimes have a concept, and some (mutable) Definition object of the concept, basically holding collected data, used to build the "proper" object
<snusnu>
finalization then is transforming the "definition" objects, into the eventual, immutable object that represents the concept
<snusnu>
only, it happens *as* the system is being built .. not in some dedicated step at the end
<snusnu>
mbj: thoughts?
<snusnu>
mbj: i dunno if i described my ideas properly, but i think you mostly take a similar approach
<snusnu>
to some respect, i have the feeling that finalization is about being "lazy" in terms of modelling the domain/system (and especially, the various states the system is in, while being built)
<dkubb>
snusnu: one way to handle this, which I did for Axiom::Relation::Variable, is I have a "mutable" proxy object which accepts all the same methods, and sends them to the underlying mutable object to get a new object back, then it updates it's internal pointer
<dkubb>
snusnu: finalization of such an object would simply be to return the inner object and throw away the mutable wrapper
<snusnu>
dkubb: i think i know what you're getting at .. i guess what i'm leaning towards, is giving that proxy thing a more "concrete" name .. make it "participate" in the (names) of states that occur while a system is being built
<dkubb>
not that this has a #finalize method, but it could easily contain one
<snusnu>
that is not to say i don't like what you did there
jgaskins has joined #rom-rb
<dkubb>
snusnu: in many ways I much prefer this kind of approach to having a fully mutable version that you use as a builder type object
<snusnu>
dkubb: the relation variable is kind of a special case tho, isn't it? .. i mean, it models the concept of a variable (i.e. it gives a persistent name to something immutable, which can change)
<dkubb>
snusnu: I dunno. if we imagined that the schema was wrapped in a mutable container, then we could do this at some stage after setting it up: schema = schema.finalize
<snusnu>
dkubb: btw, the mutable builder support objects, get thrown away / aren't used anymore thus gc'ed .. when the system has "booted"
<dkubb>
where the "schema =" could be replaced with something else of course
<dkubb>
like a const_set, or whatever
<dkubb>
snusnu: yeah, I know. I was just thinking mutable builder objects seem to need to support a larger interface that may be duplicated in the immutable versions, except where the immtable versions return changed copies of themselves
<dkubb>
snusnu: it
<dkubb>
it's not something i feel super strongly about, I was just pointing it out as an alternative to the builder approach
<snusnu>
actually, i found that not to be the case very often .. the mutable objects mostly contain *data*, whereas the immutable stuff mostly contain *operations*
<dkubb>
I personally prefer to keep mutability contained in something really tiny I can audit
<snusnu>
i mean, api wise, they haven't yet looked similar all that often
<snusnu>
that is exactly my goal, keep the mutable stuff tiny, on the boundary
<snusnu>
and by boundary, i mean "construction phase" mostly .. once a system is functional, there's no more mutability involved
<snusnu>
it's hard to find words for that ;)
<dkubb>
I realize axiom is probably a special case too
<dkubb>
since it's all about transformation, even if it is immutable
<dkubb>
it transforms a relation from one state to another
<mbj>
snusnu: I think your approach will work. I prever to stay all immutable if possible.
<mbj>
snusnu: For some problems I could find "pure immutable builders". But not in the first iteration.
<snusnu>
dkubb: yeah, that's a point i guess .. other domains (the ones i worked on so far) .. mostly involve collecting data from the outside (using mutable, simple data containers) .. and then, via a few transformations, end up in immutable objects used in the functional, readybuilt system
<snusnu>
mbj: yeah, builders are mostly immutable with my stuff
<dkubb>
is there any problem with a builder that accepts inputs, and creates a snapshot of the system internally using immutable objects, then as it receives more input, it updates the immutable object to a new state.. then finalization is simply returning the current snapshot
<snusnu>
mbj: it's the named data capsules used by the builders, that are mutable
<snusnu>
dkubb: i followed you up until you mentioned "then finalization …" .. oftentimes i just don't need finalization :) .. or maybe i still misunderstood something ;)
<mbj>
snusnu: I think all designs should convergent to pure immutable systems. But I'm not possible to come up with such solutions the first time.
<snusnu>
yeah, me neither, obviously
<snusnu>
but i found that the smaller the states (names, nouns), the easier it gets
<dkubb>
snusnu: well, I use the term finalization loosely.. I more mean it as "get the current immutable system from the builder"
<snusnu>
building an immutable system oftentimes involves some sort of DSL (or rather, it oftentimes provides object that "gather data") .. for convenience, those are sometimes immutable, but they're really only the "first encounter" parts, collecting info on what is to be built
<mbj>
snusnu: BTW a builder returning a domain AST from DSL works pretty nice in my latest spikes.
<snusnu>
s/immutable/mutable above
<snusnu>
mbj: yeah, i'd expect that to be a very broadly useful abstraction, especially in domains that mostly transform from one into another representation .. which, well, most if not all programs do, one way or the other ;)
<mbj>
:D
mkristian__ has joined #rom-rb
<snusnu>
dkubb: i think the kind of finalization i have a problem with, is one (and only one) where, for the sake of laziness, intermediate state representations were left out, in order for one big loop at the end, that turns everything immutable
<snusnu>
other kinds of finalization happen all the time, like e.g. when turning something mutable into something immutable *while* constructing the immutable objects that represent a system
mkristian_ has quit [Ping timeout: 260 seconds]
<snusnu>
a side effect of that, that kinda occurred to me, is that modelling every state explicitly, instead of allowing objects to change their state, is that it's much easier to know where to look for that code … you have a noun in your head .. that's in some file
<snusnu>
it lays a bit more burden on naming things, but oh well, there's only 2 hard things in computer science .......
<snusnu>
:p
<mbj>
snusnu: +1
<dkubb>
snusnu: yeah, I think the only reason to use that "other" kind of finalization is when you have circular dependencies and you have to wait for the whole system to be known before you can finish setup
<snusnu>
dkubb: exactly, and that makes me kinda sad ;)
<snusnu>
i guess it's fair enough tho
<dkubb>
it happens.. it should be minimized though
<snusnu>
right
<dkubb>
my main thing is that stuff be immutable before normal runtime
<snusnu>
exactly, once a system is booted, it should consist of immutable objects only
<mbj>
Yeah.
<snusnu>
during boot, it might use some mutable stuff to ease construction
<mbj>
I'd love to have ruby vm beeing capable of removing all metaprogramming once VM.is_now_booted.
<mbj>
Imagine all the optimizations that could happen!
<snusnu>
yeah
<snusnu>
mbj: btw, speaking of optimizations .. it occurred to me (and i'd call it premature optimization for now) … that we could keep every fetch_key/dump_key ducktrap we build during rom mapper definitions, inside a registry .. and then reuse them in new mappers
<mbj>
heh
<snusnu>
so, every object has an :id for example
<snusnu>
all those could use the same ducktrap
<dkubb>
that would be awesome
<snusnu>
it would, right?
<mbj>
Yeah.
<mbj>
snusnu: BTW ducktrap will be dramatically simplified soon.
<snusnu>
nice!
<snusnu>
it is one of the most coolest libs ever
<mbj>
snusnu: I'll help you to port your rom mapper changes to ducktrap 2.0.
<snusnu>
:)
<snusnu>
well, i guess i'm saying that because i work on the data mapping domain, but it's not only useful for that, so yeah, i *really* like it
<snusnu>
it's one of those small, beautiful abstractions, that can be used in a lot of contexts
<snusnu>
tell me how to go back and forth, so simple
<snusnu>
heh
<mbj>
snusnu: thx
<snusnu>
mbj: btw, rom-mapper in fact is nothing more than a DSL for ducktrap, tailored for a mapping scenario, a pimped Ducktrap::Mapper
<snusnu>
s/is/will be
<dkubb>
I'm sure that the ideas behind ducktrap probably have a name that we don't know yet
<snusnu>
i hope to finish my spike by the end of the week
<snusnu>
dkubb: heh, most probably, yes!
<dkubb>
those lisp guys probably came up with it 40 years ago
<snusnu>
mwhah, true
<dkubb>
it would be interesating to see if it has other names, because we may be able to steal ideas and/or simplify some things
<snusnu>
yeah
<dkubb>
I was surprised by how much relational algebra, invented 40 years ago, is still applicable. good theories are timeless
mkristian_ has joined #rom-rb
<snusnu>
yeah, the closer it gets to "real mathematics" the more resistant to change it becomes ;)
<snusnu>
we could probably look for ducktrap in the mathematical domain
<dkubb>
I'm sure it's there
<snusnu>
yeah
<dkubb>
the closer it get to real mathematics the more well thought-out things are
<mbj>
dkubb: math does not rust!
<snusnu>
heh right
<mbj>
And yeah I'd love to know the name of that ducktrap theory.
<dkubb>
I've found before that once I found the name for something it opened up a whole world of research, and even stack overflow posts that I could read about
<mbj>
heh
<dkubb>
we built the entire DM1 query engine without knowing about relational algebra
<dkubb>
I wish we had known about it
<dkubb>
we ended up with soemthing that modelled SQL, and it was alright, but it could've been so much better
<snusnu>
yeah, and the nice thing is, that while axiom's *implementation* might well be refactored at some point, the fact that ROM is built on top of RA, seems to make the concept much, much more durable
<dkubb>
yeah, even if the api changes the idea probably won't change
<snusnu>
right
mkristian_ has quit [Quit: bye]
<mbj>
hahah: For the remainder of this post and this series, let’s discard the first possibility (since most professional programmers wouldn’t max out at or before bare minimum competence) and consider an interesting, specific instance of the second: voluntarily ceasing to improve because of a belief that expert status has been reached and thus further improvement is not possible.. This opting into indefinite mediocrity is the entry into an oblique ph