<kpwz>
solnic: I don't know what the latest situation was with the logo, but I've found myself with nothing to do today, so I'm running with the ideas I shared previously to come up with some concepts for a look and feel for the site overall.
<kpwz>
maybe there has been more discussion. It'd be good to get some sort of formal stamp on it to say ‘this is what we're going to go with for now’
<solnic>
kpwz: hey
<kpwz>
hey
<solnic>
kpwz: I was trying to ping you here
<solnic>
with no luck :)
<solnic>
we basically all really like the current proposal
<solnic>
the one you pasted here with both monochrome and colorful versions
<kpwz>
sorry, I've not checked irccloud in a few daus
<kpwz>
*days
<solnic>
np :)
<kpwz>
I'm getting pretty bad about which client I'm using :)
<kpwz>
that's good to hear though!
<solnic>
ha!
<kpwz>
alright, then I shall proceed with my conceptualising.
<solnic>
yeah so unless you want to experiment with some other ideas...we're pretty much +1 on what you already made
<kpwz>
great
<kpwz>
that suits me, I'm pretty happy with how it looks currently.
<solnic>
that's great!
<kpwz>
I'm just messing around with some ideas for how the overall site aesthetic could look. It'll be pretty minimalistic but I've got some things I want to try out that riff on the style of the logo
<cored>
morning
<solnic>
kpwz: oh that's great!
<solnic>
morning cored
solnic has quit [Quit: Leaving...]
solnic has joined #rom-rb
knowtheo1y has joined #rom-rb
knowtheory has quit [Ping timeout: 256 seconds]
<cored>
hi
knowtheo1y has quit [Quit: Computer has gone to sleep]
mbj has joined #rom-rb
moonglum has joined #rom-rb
snusnu has quit [Read error: Connection reset by peer]
<mbj>
just released mutant-0.3.0.beta8 with tons of fixes!
<mbj>
Also unparser can now correctly reproduce: def foo; bar; rescue; baz; end
<mbj>
And I have else support for rescue statement :D
djsell has quit [Read error: Operation timed out]
dkubb has joined #rom-rb
<mbj>
dkubb: hola
<dkubb>
mbj: good afternoon
<dkubb>
mbj: I just got back home from holidays
<mbj>
dkubb: nice! I'll do my next longer vacation after the eurucamp days.
<mbj>
3-4 days in berling with my family!
<mbj>
dkubb: I hope you are feeling relaxed now?
<dkubb>
mbj: yeah, fairly relaxed. it was pretty busy. glad to be home so I can code and rest ;)
<cored>
dkubb: hi
<cored>
dkubb: I did not keep working on the refactoring, because if I make any progress I wanted to share what I was finding with you
<mbj>
dkubb: I know that feeling! (both, need to code and busy in holidays)
<cored>
dkubb: but I will get some work on done on that, this week
<dkubb>
cored: no worries. I'll be able to help you this week.
<cored>
great
<dkubb>
this week I'll be continuing on the gateway for the memory adapter. I have something almost working
<mbj>
dkubb: I'll focus on mutant, I think it helps the project most.
<dkubb>
mbj: are there a ton of remaining mutations?
<mbj>
dkubb: BTW I got a 5-8% speedup with removing some unneded deep_cloning.
<dkubb>
mbj: I wonder if regexp mutations are something that's getting close to being possible?
<dkubb>
mbj: that's pretty cool
<mbj>
dkubb: I did not started with regexp mutations.
<dkubb>
mbj: oh I know, I just wondered if the low hanging fruit in mutant are running thin .. and I figured regexp mutations might be something worth considering
<dkubb>
mbj: I guess class/module body mutations are something to consider too?
<mbj>
dkubb: jo, but I have other stuff that comes first.
<mbj>
dkubb: I have some generated syntax errors on self-hosting mutant
<dkubb>
mbj: ahh ok. is there a list of things you're thinking about?
<dkubb>
oh right
<mbj>
Than I'd love to resolve the signalling issue
<mbj>
bug vs kill
<dkubb>
I guess getting mutant to pass through mutant would probably be fairly high
<mbj>
TBH, I dont think so.
<dkubb>
no?
<mbj>
I mutation covered far bigger domain specific libs before with mutant 0.2
<dkubb>
I always think it's funny when tools don't work with themselves :P
<mbj>
zombie is actually really stable.
<dkubb>
oh I see what you meant
<dkubb>
I thought you were saying that mutant passing through mutant wasn't important to do ;)
<mbj>
Only the mutation mutant produces cause syntax errors, mutant did not had **any** crash running in zombie.
<mbj>
nope
<mbj>
Fixing that syntax errors is part of the 100% self covered process :D
<dkubb>
it would be nice to try to get you some help with mutant. it's super interesting imho
<mbj>
dkubb: just start, you'll love the code :D
<mbj>
If you need something you can start with, tell me what you are interested in and I'll guide you.
<dkubb>
well, I have done some things, and I would love to work more on mutant, but I probably need to help on the axiom side the most now
<mbj>
IMHO the "todo" list is big enough to let us be guided by interest
<dkubb>
yeah, but if I don't do the axiom stuff I don't think anyone else will take it
<dkubb>
and it's foundational and important
<mbj>
I have a clean need to generalize gateways.
<mbj>
I wrote 4-8 of them (depends on how you count).
<dkubb>
I have started work on that with Axiom::Relation::Proxy
<dkubb>
I'm using it on the memory gateway with good results
<mbj>
Maybe we need a fundamentally differend approach for the gateways. All that metaprogramming, method_missing handling etc feels so overengienieered.
<mbj>
(sorry I cannot spell last word, confuses my brain to many vowels.)
<dkubb>
I think we could probably do it with a simpler structure, like inheriting from BasicObject and mixing in a module or using Delegate
<mbj>
what about remove the need to handle all that dsl methods?
<dkubb>
I think we could
<dkubb>
but it depends on what the adapter can do
<mbj>
Maybe we could refactor axiom a bit to use an ast internally as main representation.
<dkubb>
if you can "push-down" the operation (meaning the adapter can handle it), then you can simply delegate the message to the underlying relation and wrap the return value in a new gateway
<mbj>
Processing ASTs with #type, #children interface is a way easier than all that methods you can call on Axiom::Relation
<dkubb>
if you can't push-down, then you need to pass the gateway into the new operation
<mbj>
We still could use that code, (Axiom::Relation:*)
<dkubb>
there's also the case where you're doing cross-adapter
<mbj>
Yeah
<mbj>
The "Root" object would handle the dsl
<mbj>
And test for such cases, but I more and more feel our primary abstraction is to complex.
<mbj>
I'll have to prove this via a PR, I know.
<dkubb>
yeah
postmodern has joined #rom-rb
<dkubb>
I find proxy objects with conditional push-down to not be particularly complex, but I do agree that it could be made simpler for implementers
<dkubb>
if they had some kind of way to describe the capability of the adapter the generation of the gateway object could mostly be automated
<dkubb>
those 3 cases pretty much cover all the use cases
<dkubb>
per operation I mean
<mbj>
yeah
<mbj>
But pls remember a simple I_CAN_HANDLE = [:restrict, :foo, :bar] is too limiting.
<dkubb>
I know
<mbj>
okay
<mbj>
mongo for example cannot handle a restrict on top of an offset
<mbj>
but it can handle an offset top of an restrict
<dkubb>
some adapters can only handle AND, and the only way to represent an OR would be to actually transform the query into an in-memory union
<mbj>
yeah
<dkubb>
I don't know what a generalized gateway would look like. I think you'd be taking more complexity into the lib and away from the adapters
<dkubb>
I don't yet know, even with ~10 gatways, we have enough data to do it properly yet
<mbj>
We had an idea of some kind of a state machine inside the adpaters already.
<mbj>
s/adapters/gateway/
<dkubb>
there *is* a state machine. it's just not explicit ;)
<mbj>
hehe
<mbj>
yeah
<mbj>
I imagine it the following way:
<dkubb>
an explicit state machine would give us a nice framework to hang more logic from
<mbj>
We should use a functional style state machine.
dkubb has quit [Read error: Connection reset by peer]
dkubb has joined #rom-rb
<mbj>
dkubb: I found more bugs in latest mutant :(
<mbj>
It for some reason excludes public methods now when running it directed.
<mbj>
aka giving it a specific subject
<mbj>
Seems to be the first bug that is only visible unde zombie
<mbj>
dkubb: Can you verify mutant mutated methods with a memoizer correctly before?
<dkubb>
mbj: I can, but not this minute. just catching up on some work now that I'm back
<mbj>
dkubb: Maybe I found the megabug :D
<mbj>
class Foo
<mbj>
include Adamantium
<mbj>
def bar
<mbj>
end
<mbj>
memoize :bar
<mbj>
end
<mbj>
mutant ::Foo # would NEVER mutate Foo#bar
<mbj>
And maybe this was / is also present in 0.2
<mbj>
It ignored that subject silently because it could not find source ast.
<mbj>
Foo.instnace_method(:bar).source_location points to adamantium :D
<dkubb>
oh interesting
<dkubb>
mbj: so you're saying because adamantium overwrote that method with it's own memoized version, those methods were never getting mutated
<mbj>
dkubb: IMHO, yes.
<mbj>
I just fixed the silence, but I'm stunned :D
<mbj>
it is possible to add a special case for adamantiums memoizer
<mbj>
But I had fully mutation covered libs in production without any bug report
<mbj>
And now it turns out they might have 70% coverage :D
<mbj>
dkubb: I need to recover the memoized methods source locations
djsell has joined #rom-rb
<mbj>
dkubb: Options I see, provide a public api such as: memoized_method(:name) => Unbound method.
dkubb|away has joined #rom-rb
<dkubb|away>
mbj: heh, better to find out sooner than later
dkubb has quit [Ping timeout: 248 seconds]
dkubb|away is now known as dkubb
<dkubb>
mbj: I wonder if there's any way to identify the stuff that adamantium is doing?
<mbj>
dkubb: I checked, there isnt.
<mbj>
dkubb: Most likely I have an epic bug in mutant.
<mbj>
dkubb: And all our 100% coverage is a lie.
<cored>
does virtus make the valueobjects inmutable
<cored>
?
<mbj>
cored: jo
<cored>
mbj: hey, what's up
<cored>
or it was that a 'nop'
<mbj>
cored: sorry jo is yes.
<mbj>
cored: germany slang, sorry :D
<cored>
hehehe
<cored>
is ok
<cored>
I see, trying to go all the way DDD style for my next project
<cored>
been doing service record wrappers on Rails apps with an anemic domain model so my specs run fast
<mbj>
dkubb: So I think we need to add something to adamantiums public api.
<mbj>
dkubb: For example define a method like ${memoized_name}_original_source_location ?
<mbj>
cored: nice, do you feel a productivity difference?
<dkubb>
mbj: there's always alias method chain :(
<snusnu>
mbj: so, if i tend to just initialize ivars in #initialize and provide an attr_reader, instead of memoizing parameterless methods … mutant is doing its job fine for that code i assume …
<snusnu>
hey guys :)
<dkubb>
mbj: the reason why it's hard to mutate is because adamantium removes all record of the original object, correct?
<snusnu>
fwiw, i always liked to initialize ivars more than memoize from adamantium .. it's a matter of taste tho, i guess
<cored>
mbj: more or less, I'm doing that on already existent projects
<cored>
mbj: I found myself awknoledging that I have lacking design skills which I'm trying to learn
<cored>
reading DDD/GOOS
<cored>
there's something about GOOS approach which I don't like because I just try it but then again I'm just starting the book maybe they talk about how to taclked that later on, what I tried was to use acceptance test to drive my application but I was hittig the UI which also is slow, at first I was using selenium and then I switch to use capybara-webkit, but stills I feel there's should be a better way
<cored>
dkubb: latest failed spec was on self.class.type inside Attribute, let me show you which spec
<snusnu>
mbj: of course, i thought so, i mean, why wouldn't it :)
<mbj>
dkubb: jo, it redefines the method and nukes original source location
<mbj>
dkubb: And the mutant method matcher does silently ignore subjects when it cannot find the ast.
<mbj>
s/does/did/
<dkubb>
mbj: alias method chain probably won't nuke it
<dkubb>
mbj: it might be possible to use parser/unparser in adamantium?
<mbj>
dkubb: jo, but this is overkill IMHO.
<mbj>
mom pr my change.
<dkubb>
mbj: what if we added adamantium/mutant or something that you could require in mutant
<snusnu>
guys, i'm totally not bitching here, what are your reasons to prefer a memoize "macro" over just initializing stuff in the constructor?
<dkubb>
mbj: it could use a different strategy, one amenable to mutant.. it could use string class eval
<snusnu>
i genuinely want to know
<dkubb>
snusnu: I dunno, I guess I just don't like #initialize to have all that setup code in one place
<dkubb>
snusnu: I like the idea of marking a method explicitly as idempotent
<mbj>
dkubb: I'd prefer a clean public interface.
<mbj>
dkubb: So if a method got memoized it is okay to change the source location
<snusnu>
dkubb: ok, the first one is a matter of style i guess, which is totally fair enough . the latter is a good point, it makes the behavior more obvious (being idempotent i mean) .. "then again", it's equally obvious (without further "tricks"), if it's written with one time initialization plus only a reader
<mbj>
dkubb: I'm fine with adding a special case to mutant that detects memoizers and uses differend source location location.
<dkubb>
mbj: what if we reuse the existing source file and location when evaling it?
<mbj>
dkubb: This hides the truth!
<dkubb>
heh
<mbj>
dkubb: The truth is we did metaprogramming and it should be in the call stack.
<snusnu>
dkubb: that being said, i'm obviously fine with all approaches, but for myself, i'm probably going to just stick with initialization in the constructor (for non-rom code at least)
<mbj>
snusnu: memoizers are very handy for lazy computation.
<cored>
did I miss something?
<dkubb>
snusnu: in my specific case, I think one thing I'd like to try is to actually have *all* methods memoized/idempotent by default, and then I would explicitly state which are command methods and should not be memoized
<snusnu>
mbj: that's true, i guess you're talking about methods which might or might not be called on an object?
<mbj>
snusnu: jo
<mbj>
snusnu: You are german so I can say "jo" :D
<snusnu>
lol yeah, it even sounds austrian :p
<mbj>
hehe
<mbj>
dkubb: We could also have a method returning the original unbound method.
<dkubb>
mbj: that actually sounds better
<mbj>
dkubb: My original_source_location thing in the PR is only to start discussion.
<dkubb>
mbj: actually, if we have "__#{method_name}_original" we could just use amc
<mbj>
dkubb: But than I'd like to add something like original_method(:name)
<snusnu>
dkubb: by all methods, you mean all methods with arity == 0 i suppose?
<dkubb>
snusnu: yeah
<mbj>
dkubb: mhh not so good.
<mbj>
dkubb: original_instance_method(:name) ?!
<dkubb>
snusnu: although techincally it is possible to memoize methods with arity > 0, cache invalidation is annoying
<dkubb>
mbj: sure, that works
<snusnu>
dkubb: yeah, probably not worth it most of the time
<snusnu>
ok, thx for the explanation, i found a new rule for me i guess .. if possible, stick to initializing ivars, if lazy, use memoize
<dkubb>
mbj: looking at adamantium I think we could probably refactor it a bit more. I would probably make it so the "memory" Hash has a default proc that does a bunch of the work
<mbj>
dkubb: So I'll add a patch that keeps track of all memoizations happened in a hash { name => unbound_method_instance }
<dkubb>
mbj: it could use the registry of original methods internally
<mbj>
dkubb: That interface I'll add will use that hash.
<snusnu>
i dunno, i somewhat like to see initialization code in #initialize .. if it's a *lot* it might be a sign the class is doing too much, in any case, i know where to look at for initialization, the constructor, no surprise
<mbj>
dkubb: Registry, wich one?
<dkubb>
mbj: the way it's using memory.fetch now is probably not what I'd do today. I mean, the behaviour is identical for all memoized methods so I'd tend to define that up-front in the Hash default proc
<dkubb>
mbj: I was just saying a registry would be that object that maps the name to the unbounded method instance
<dkubb>
mbj: a concept we don't have yet
<mbj>
dkubb: I'm about to add this Adamantium module instance specific registry.
<dkubb>
mbj: sure, then I'll comment on it in the PR
<dkubb>
mbj: If it works I'll probably just merge it as-is and then look at further refactorings later
<dkubb>
mbj: it's more important to me that we get something mutatable first. I can optimize/simplify later
djsell has quit [Quit: Leaving.]
<mbj>
dkubb: yeah, we agreed on public api already, so we can prettify internals later.
<dkubb>
cored: so with the Attribute* specs I would probably define an attribute subclass right there, with the types class method in it. you could also push that into a shared context since it'll probably be the same for all of them
<cored>
dkubb: an attribute sub class in the spec ?
zekefast has quit [Quit: Leaving.]
<cored>
dkubb: but the described_class is Class.new(Attribute) Attribute doesn't have the actual definition for self.type
<cored>
dkubb: all the child classes do have it, though
<dkubb>
cored: yeah, that's why I was saying do something like: Class.new(Attribute) { def self.type ... end }
<dkubb>
cored: so you're effectively creating an object that you can use to test with
<cored>
I was about to stub that method
<cored>
but wanted to confirm, first
<dkubb>
yeah, that works too.. same idea
<cored>
cool
<cored>
guessing that the type is Types::Atribute for class, right ?
<dkubb>
cored: you can use Types::Object if you wanted
<dkubb>
we just need a stand-in to work with so we can test the actual Axiom::Attribute methods
<dkubb>
I'd use Types::Object because it's the least specific type with an actual primitive and some constraints
<cored>
dkubb: I returned Attribute for that particular spec
<mbj>
but my code does not, according to rspec it fires a KeyError
<mbj>
Also verified with --backtrace there is no proxy problem.
<dkubb>
cored: yeah I think your change was good. for this change #type should generally return an Axiom::Types::Type subclass
<dkubb>
mbj: if you push it I can look at the spec
<mbj>
dkubb: did already.
<mbj>
dkubb: +an rbx change and 1.8 removal.
<cored>
dkubb: well, maybe those specs that are not failing with Types::Object could stay like that this one could return Attribute, the only downside for me is the incosistent spec
<cored>
dkubb: there are a lot of small commits and also I was pushing changes to the branch
<cored>
do we have any general rule for commits/pushes and when to create a PR
<cored>
?
<dkubb>
cored: it's already in a PR
<dkubb>
cored: I generally create a PR on my first commit to a branch ;)
<dkubb>
if I can
<dkubb>
cored: for this, since it's a WIP, we mainly just want to get things working in the branch. we can rewrite the commits to make more sense later before merging into master
<cored>
I see
<dkubb>
cored: also think we *should* fix existing specs to use the new api even if they are passing
<cored>
I just think I was to fast fixing failing specs and not notice that this is pointing to an Aggregate
<dkubb>
it's confusing otherwise, especially if someone tries to use those specs to do another refactoring
<cored>
Aggregate, "#type"
<dkubb>
I would be more likely to focus on fixing failing specs first, the do another pass looking for these kinds of problems later