solnic changed the topic of #rom-rb to: Ruby Object Mapper | Mailing List: https://groups.google.com/forum/?fromgroups#!forum/rom-rb | Logs: http://irclog.whitequark.org/rom-rb
dkubb has quit [Quit: Linkinus - http://linkinus.com]
snusnu has quit [Quit: Leaving.]
dkubb has joined #rom-rb
<elskwid> dkubb: Thanks for looking over that code!
<dkubb> elskwid: no worries
<dkubb> elskwid: that's some really nice code
<elskwid> dkubb: Aw shucks.
<elskwid> That means a lot!
<elskwid> dkubb: Good catch on skipping the module eval, at that point my brain was so liquified I just put down what was working.
<elskwid> ha ha
<dkubb> hehe
<elskwid> dkubb: All cleaned up.
<dkubb> sweet
<elskwid> dkubb: It's been a blast to play around in here. Looking forward to getting involved in the other libs if you guys will have me.
<dkubb> yeah, for sure
<dkubb> there's so many things that are really interesting in this area
<dkubb> we're not just building an ORM, it's a toolkit for building your own ORM
<elskwid> dkubb: I've lurked for far too long. ha. Figured I'd better speak up when I saw solnic's post on the parley list.
<dkubb> of course, we'll have some recommended configurations, and probably metagems that package things up in a few common ways
<elskwid> dkubb: Yes. I've watched with interest.
<elskwid> and of course, I can't stand the ORM I use day-in-and-day-out
<elskwid> dkubb: It's such a smart way to do it. We do the same thing for our internal dependencies.
<elskwid> Similar to your devtools just not as crazy.
<elskwid> HA!
<dkubb> hehe
<dkubb> devtools is pretty crazy
<elskwid> I mean that in a good way...
<dkubb> but it saves a ton of time I think
<elskwid> We just have ours in a metagem but I can see why you do it the way you do.
<elskwid> and yes, the gains far outweigh the weirdness.
<elskwid> Just havint a toolset in sync is HUGE
<dkubb> because it helps get all the low hanging fruit out of the way before code needs to be reviewed.. making the code reviews able to focus on higher level stuff
<elskwid> *having
<dkubb> I still do one low level pass beforehand though
<dkubb> just because no tool is perfect
<dkubb> and I find my brain gets hung up on small things first. once they're taken care of I'm able to see the bigger picture
<elskwid> dkubb: What do you mean one low level pass? Do you mean review your code?
<dkubb> when I review code I usually do two passes
<dkubb> my first pass is just looking at the code structure. variable names, idioms, etc
<dkubb> just kind of low level stuff.. like how the code was put together
<dkubb> when I do a second pass I'm usually looking at higher level design. how the classes fit together, the overall feature the code is trying to add, how it fits in with the rest of the code, etc
<dkubb> I can't do both passes simultaneously because I can't context switch between the two. I think they require different ways of thinking
<elskwid> I hear that.
<elskwid> I'm currently struggling with a switch to emacs. I was telling solnic earlier that I had no idea how much I relied on the tree view (or folders or whatever) to help me maintain project-level context.
<dkubb> code reviews are also a good way to communicate. it's one thing to talk about how you'd do something, but to have a working example to discuss is 10x better .. it gets everyone on the same page and is a good way to transfer skills
<dkubb> heh
<elskwid> dkubb: Yes!
<dkubb> I made the switch to vim a year or two ago and it was hard
<elskwid> dkubb: I'm thinking that pull requests should be opened the second you have code down that runs.
<dkubb> but I love it. I wouldn't go back to what I was using before (Textmate)
<elskwid> It has been huge for me to have you guys looking over that pull request.
<elskwid> dkubb: I was on Sublime.
<dkubb> elskwid: heh, sometimes at work I make a commit with --allow-empty, add a comment, and then push the new branch. I open a PR with that branch
<elskwid> dkubb: Perfect.
<dkubb> the nice thign is that the comment is used as the PR description
<elskwid> I think that is a great way to do it.
<dkubb> this only works if you have a single commit though
<Gibheer> morning
<dkubb> Gibheer: good evening
mbj has joined #rom-rb
<mbj> .
<dkubb> mbj: I laid out a few really simple skeleton files for sql
<dkubb> mbj: I've also added you as a committer
<dkubb> mbj: good idea to start with the AST outline.
<mbj> dkubb: yeah
<dkubb> mbj: should we start with a few simple SQL queries as goals for what we want to be able to parse and generate? something simple like SELECT * FROM users
<mbj> dkubb: I typically start with literals, boolean expressions and than the more complex stuff
<mbj> dkubb: makes more fun with specing
<dkubb> mbj: ok, so you build up from the smallest primitives?
<mbj> dkubb: Yeah, I did this so often and it turned out bottom up works.
<dkubb> mbj: ok, I'll follow your lead on the parser/ast side of things ;)
<mbj> dkubb: thx
<mbj> dkubb: The main reason is: Specs look really nice!
<dkubb> mbj: luckily I think SQL syntax is probably simpler than ruby
<mbj> dkubb: So once you have something like s(:select, s(:all_fields), s(:identifier, :users))
<mbj> dkubb: For this you need to specifiy the s(:identifier, :users) first
<mbj> * specify how this should be generated.
<mbj> will go really smoth, I'll redo aql with this style, and yeah sql will probably many times more easy than ruby
<dkubb> are you still thinking about using ragel?
<mbj> We could also try to do it in parselet
<dkubb> I don't mind ragel if you want to use it
<mbj> So the whitequark ruby parser uses ragel for tokenizing and racc for parsing
<dkubb> I've kinda been interested in learning it. either one is fine with me though, I'll let you decide
<mbj> We should reuse an existing grammar if possible
<dkubb> like BNF?
<mbj> Yeah, steal something from sqlite, postgres
<dkubb> here's the ANSI SQL: http://savage.net.au/SQL/
<dkubb> at first I was going to focus on ANSI SQL, then branch out to different dialects
<mbj> Yes, ideally we reuse prior work and port it to pure ruby
<mbj> So postgresql should work?
<mbj> lemme dig their source for what they use
<dkubb> postgresql SQL is more like a superset
<dkubb> and I don't think any SQL engine actually implements all of SQL-92 even
<mbj> But stripping down a superset that already works is less time and efford than writing a new one?
<dkubb> they all use somewhat overlapping subsets of ANSI 92, with their own extensions
<dkubb> fwiw, postgresql is the reference db I used in the first sql generator
<mbj> SQL is design by comitee, so I fear I'll get bored reading the spec in depth
<dkubb> heh
<dkubb> I thought we might focus on the subset of SQL we actually need first, and then branch out after that
<mbj> We'd only have to write our own actions
<mbj> And strip parts we wont support now
<dkubb> it looks like they embed source right inside the y file
<dkubb> btw, would that y file be called the grammar?
<mbj> yeah
<mbj> the embedded source is called action
<mbj> And C in this case.
<mbj> So we IMHO should reuse it, and copy over parts we want to support.
<mbj> Starting with literals
<mbj> followed by operators
<mbj> followed by identifiers
<dkubb> ahh ok, so we strip out all that stuff. and try to minimize the code we embed within it, delegating to something else
<mbj> Yeah
<mbj> But we already have precedence rules etc for free.
<dkubb> to start with I think we want to only support DML, we can remove DDL stuff although eventually I would like to generate it for migrations
<dkubb> ahh nice
<mbj> We call methods on the builder object within actions
<mbj> I'd just clone the whitequark design here.
<dkubb> oh I see, and the builder puts those into an ast or a stack or something as they are seen?
<mbj> yeah
<mbj> Also I think peter (whitequark) will be able to help us in a dead end. We are both not parser gods ;)
<mbj> But lets play around before calling for help ;)
<dkubb> and then this y file is used by ragel to generate ruby source that tokenizes the sql
<mbj> not by ragel
<mbj> .y files are processed by racc
<dkubb> ahh I see
<mbj> into giant .rb files
<mbj> parsers only work on tokens
<dkubb> so racc builds the parser from this
<mbj> Ragel is used in whitequark/parsers to break the input source into a token stream
<mbj> That gets consumed by the parser defined in the .y files
<dkubb> ahh I see
<mbj> racc is able to generate a parser with a lookahead of one token (fast).
<mbj> ragel is not!
<dkubb> what's the speed on all this?
<mbj> It depends on the complexity of the grammar
<mbj> For example ruby must be tokenized and parsed at once.
<dkubb> OT, but can this be used to parse a stream? i.e. does the whole string need to be known before parsing can start?
<mbj> depends
<mbj> I typically say stream processing is a lie, because the last character of the stream can still make the whole input invalid.
<dkubb> right
<mbj> stream processing implies you need error tolerance
<mbj> An parser generated by racc only needs one token lookahead
<mbj> So it is pretty fast. But I dont have measurements here, nor the theoretical background.
<mbj> I like to get stuff working and correct first ;)
<dkubb> yeah, I was mostly curious
<mbj> Once I talked to whitequark I also asked the same
<mbj> The parsers generated by racc are from the "fastest" class because of the one token lookahead.
<mbj> And no need for backtracking
<mbj> But as ruby drives the parser it will still be slow
<mbj> I noticed a 200% penalty when going from melbourne to whitequark/parser
<mbj> But this is okay for 1.9 2.0 and 1.8 support
<mbj> And for pure ruby. That 200% where on MRI, I expect JITed rubies can easily optimize that generated parsers.
<dkubb> once we have a good pure ruby reference implementation, I suppose someone could always optimize it in C or java
<mbj> Yeah
<mbj> And we can measure what exactly is slow
<dkubb> if it's 100% covered, and mutated, then our test cases will help make a faster version bullet proof
<dkubb> yeah
<mbj> I think it is possible to parse SQL with a pure ragel parser
<mbj> But lets start with a proven approach ;)
<dkubb> yeah
<dkubb> the round-trip tests, etc all will still be valid
<mbj> BTW the tokenizer in MRI was "handwritten", I really hope some implementations use the whitequark thing
<mbj> I'd love to write an RBX compatible bytecode emitter.
<dkubb> so above you said you wanted to start with literals. we could first parse a literal into an AST, then generate it so we can round-trip it. then we could look at the fuzzer side of things.. going node-type by node-type
<mbj> yeah, but maybe I'll go faster and cover more nodes for generation
<mbj> Than dealing with the parser
<mbj> This allows me to spot cases where the target AST is misdesigned.
<mbj> Round trip tests are really nice I know, but my time is limited.
<dkubb> you can attack this from any angle you want ;)
<mbj> If we have a stable target ast we have all we need to plug this into axiom
<mbj> Basically we transform the axiom ast (node tree) into an sql ast.
<dkubb> yeah
<mbj> The better the sql ast is desiged, the more fun we'll have doing this.
<dkubb> then I'll be optimizing the sql node
<dkubb> er ast
<mbj> Yeah
<mbj> First do a naive 1:1 translation
<dkubb> there are some optimizations we can do, like transforming a natural join into an inneer join
<dkubb> yeah
<mbj> And than collaps nodes where possible.
<dkubb> yeah, I already learned a bunch of the collapsing rules
<mbj> nice, and IMHO it will be fast enough
<mbj> I do not care if axiom -> axiom-optimizer -> axiom-sql-generator -> sql-optiomizer take 5-10ms
<mbj> The typical db roundtrip will be longer
<mbj> And if we can use a more complex query that loweres the number of sql queries we already won.
<dkubb> yeah, the cost in time to optimize an sql query is probably 1/100th to 1/10th of a ms
<dkubb> at least in terms of collapsing, pruning and transforming
<dkubb> what we're really doing is normalizing
<mbj> yeah
<dkubb> axiom-optimizer is super fast. it's much less than that, and it's probably the most expensive part
<mbj> I'm preparing child for kindergarden and move to office, back in 30min
<dkubb> k, I will probably be sleeping then, so good night!
<elskwid> dkubb: Who needs sleep?
<dkubb> heh
<elskwid> mbj: Hi, and have a good day!
<dkubb> I'm off now, good night
dkubb has quit [Quit: Linkinus - http://linkinus.com]
<mbj> elskwid: morning, same for you
<mbj> elskwid: Happy you liked our code review rage ;)
<elskwid> mbj: How could I not?
<elskwid> It was great.
<mbj> We arent in sync with 100% of style.
<elskwid> mbj: It all just makes the end result that much better.
<mbj> dkubb, snusnu, solnic and me are not in sync for all of what I call dm2/rom-style
<mbj> but I like to talk about code, a lot.
<elskwid> mbj: I'm not worried about it. There's lots of moving parts and they seem to be moving quickly.
<mbj> Yeah
<mbj> elskwid: You ran mutant already?
<elskwid> mbj: I didn't. Plan to in the morning.
<mbj> I have to run, bbl in 25 - 40 min.
<elskwid> okay
<elskwid> I will be offline. You have a good day!
<mbj> elskwid: hah
<mbj> elskwid: So see you lots of later ;)
mbj has quit [Ping timeout: 240 seconds]
dkubb has joined #rom-rb
solnic has joined #rom-rb
<dkubb> !memo mbj if you want to know which literals to start with, this is probably a decent reference for what axiom needs: https://github.com/dkubb/axiom-sql-generator/blob/master/lib/axiom/sql/generator/literal.rb
<dkubb> whops, no cinchy bot here yet :(
solnic_ has joined #rom-rb
solnic has quit [Read error: Connection reset by peer]
solnic_ has quit [Read error: Connection reset by peer]
solnic has joined #rom-rb
dkubb has quit [Quit: Linkinus - http://linkinus.com]
<solnic> dkubb: yeah we gotta add cinchy...if I only knew how I would've already done it :)
<solnic> lol crap
mbj has joined #rom-rb
<stormwind> solnic: maybe it's easy and the bot just need an invitation?
<mbj> .
<mbj> Nuke, nuke, nuke 1.8
<mbj> Go to hell!
<solnic> mbj: :)
<solnic> mbj: no idea if dkubb treats axiom as rom-related
<solnic> mbj: also, I think axiom deserves its own org account
<solnic> but dan probably won't like that, it's his precious after all :)
<mbj> I'm okay with axiom in dkubb account
<mbj> Lets reduce the number of endpoints...
<mbj> solnic: I'll do another refactoring soon but unparsing an ast node is really really easy: https://github.com/mbj/unparser/blob/master/lib/unparser/emitter/literal/range.rb
<solnic> mbj: I see axiom as a suite
<solnic> so an org would fit
<mbj> solnic: This is range
<solnic> but it's totally up to dan
<mbj> solnic: nodes look like s(:irange, start, end)
<solnic> I don't care where it is but I think it would look nice in its own org account :)
<mbj> Node#type => :irange
<solnic> mbj: ok looking
<mbj> Node#children = [start, end]
<mbj> Emitters register themselves under a specific type
<mbj> See the singleton level method call
<solnic> mbj: ok this looks quite clean
<mbj> Yeah
<solnic> mbj: so what do we actually need for sql
<solnic> sql has its own ast
<solnic> so axiom-sql-generator would take axiom ast and translate that to sql ast
<solnic> rite?
<solnic> and the benefit here is that we can easily transform final sql statement by modifying sql's ast rite?
<mbj> Describing want nodes represent
<mbj> Yeah!
<mbj> That is the main idea.
<solnic> this totally makes sense
<mbj> Transform axiom into an sql ast, and optimize this one.
<mbj> For example we'll start with literals.
<solnic> but sql is just an ast
<mbj> s(:string, "foo")
<solnic> axiom will optimize it
<mbj> We'll have two optimizer stages
<mbj> One that works on axiom-relations
<mbj> And one that is adapter/language specific
<mbj> For example optinizing natural to inner joins
<solnic> yes
<mbj> s(typ, child_a, child_b, child_n)
<mbj> mom
<solnic> so for instance collapsing nested selects into an inner join will happen in axiom-sql-generator
<solnic> rite?
<mbj> Or an sql-optimizer ;)
<solnic> no please no
<mbj> haha
<mbj> Axiom-sql-generator can ship this feature
<solnic> it should ship this feature
<mbj> If we go crazy and it grows to much we can ship a separate gem
<solnic> axiom-sql-optimizer makes no sense
<solnic> mbj: it's quite possible we will have >20 gems that you have to install in order to use ROM
<solnic> I already see people bitching about this
<solnic> I partially understand that btw
<solnic> but it's just that rubygems could do better :P
ddfreyne has quit [Excess Flood]
<solnic> we're missing "package" distribution or something
ddfreyne has joined #rom-rb
<solnic> so that people don't see what exactly is being installed within a given package
<solnic> I mean, we can use meta-gems
<mbj> solnic: TBH I dont care off people so much. I do this not for "imaginary people". I do this because I need a good mapper.
<mbj> So im dogfooting, I'm okay with some more gems.
<solnic> but that's really just a workaround
<mbj> rails/rails is also a workaround :D
<solnic> yes it's a meta-gem
<solnic> as I said
<mbj> yeah
<mbj> I'm talking more about the reo
<solnic> well, I do care what people think and say
<mbj> s/reo/repo/
<solnic> ignoring that is a mistake
<mbj> As long as gem install rom does the job?
<solnic> true
<solnic> anyhow
<solnic> mbj: I'm thinking about a kickstarter
<solnic> but instead of a ROM kickstarter
<solnic> we could narrow it down
kleech has joined #rom-rb
<solnic> my priority is to make whatever it takes to get awesome sql generator done
<solnic> I have some time this month but I'm sure it's not enough
<solnic> so basically I was thinking about a kickstarter just for rom sql part
<solnic> if it reaches the goal we can do another one for rom
<mbj> Dunno if people would like to fund an sql generator, without a mapper
<solnic> well, it's what's blocking us
<mbj> So lets fix it ;)
<mbj> It is not hard
<solnic> ok
<solnic> let's see how it goes this month
<mbj> The syntactic fore of sql is 10% of ruby
<mbj> s/fore/core/
<mbj> And writing unparser took around 10hours (netto) stretched around some days.
<mbj> So I expect I could define an ast and unparse it into an SQL string in 2 dedicated hours deep into the zone.
<mbj> I rarely enter the zone these days, but it would be a start.
<mbj> If we only support natural/inner/select/update/insert plus some of the basic literals it wont take long.
<mbj> +identifiers
<solnic> mbj: ok go get into the zone then
<solnic> NAU
<solnic> :D
<mbj> haha
<mbj> busy, have to make sure I finsihed *all* stuff when I enter my new project.
<mbj> All stuff of my current projets...
<solnic> mbj: sure
<solnic> mbj: just ping me when you can start
<mbj> I'd love to dedicate to opensource you know.
<solnic> I'd love to help (and learn)
<mbj> It is very easy, you would pick it up in seconds
<mbj> read unparser/emitter.rb and some random nodes.
<mbj> Once you got this one you can start now.
<mbj> I'd just copy that code.
<solnic> mbj: no sorry it's black magic for me
<solnic> as in I don't know how to start
<solnic> you gotta start, I can follow up
<mbj> It'll look exactly the same...
<mbj> You can scroll back some commits! :D
<mbj> Imagine it as a recursive visitor that instantiates a context for each visited node
<mbj> And uses this context to emit into a shared buffer.
<mbj> That context is the Emitter
<mbj> solnic: Once I push the literals you'll pick it up, for shure.
<solnic> mbj: please if you could do just this
<solnic> I could continue based on your kickstart
<mbj> okay, I'll do this now
<solnic> not to confuse with the crowd-founding campaign :D
<solnic> I literally meant a kickstart :)
<solnic> wow sweet!
<mbj> hope my GF does not catch me doing non clients coding
<solnic> lol
<mbj> Never tell your GF how to use git/github/circleci output for determining if you did commercial or opensource stuff ;)
<solnic> every time I do OSS my wife is joking that I'm doing good deeds to get to "programmer's heaven" lol
<mbj> OMG our wives will unite at eurucamp...
<solnic> that's kinda disturbing ;)
<mbj> I hope yours only speaks polnish, but this chance is so utlra low.
<solnic> mbj: she actually speaks english fluently :P
<solnic> mbj: I'm gonna do some minor housekeeping work on sql now
<mbj> haha
<mbj> I'm also doing sql housekeeping, mom
<mbj> *did
<mbj> done, pls rebase
<solnic> oh ok
<solnic> I haven't even cloned it yet
<solnic> doing so now
<solnic> mbj: damn I really hope by saying 'rom related gems' dkubb also meant axiom
<mbj> solnic: I think so, but I'll not nuke 1.8 without his explicit answer...
<solnic> yes
<solnic> it wasn't clear enuogh
<solnic> so let's hold off until he confirms
<mbj> Yeah
travis-ci has joined #rom-rb
<travis-ci> [travis-ci] Build details : http://travis-ci.org/dkubb/sql/builds/7833748
travis-ci has left #rom-rb [#rom-rb]
<travis-ci> [travis-ci] dkubb/sql#8 (master - ba142fe : Markus Schirp): The build was broken.
<mbj> solnic: BTW I'll support indentation!
<mbj> solnic: So complex queries will not look that stupid
<solnic> mbj: we could do that for pretty formatting inside logs
<mbj> solnic: Also it is a way easiert to debug ;)
travis-ci has joined #rom-rb
<travis-ci> [travis-ci] dkubb/sql#9 (master - de55155 : Markus Schirp): The build was broken.
<travis-ci> [travis-ci] Build details : http://travis-ci.org/dkubb/sql/builds/7833782
travis-ci has left #rom-rb [#rom-rb]
<mbj> I need to port mutant to 2.0.0 soon
<mbj> Regardless how nice chruby is, I always run into staring at "mutant is not included in the bundle"
<solnic> mbj: yeah we should also talk about some style-related things
<solnic> I disagree with some of the things I see
<solnic> I want us to be on the same page
<solnic> damn, I wish Dan was in our TZ
<mbj> haha
<mbj> yeah
<mbj> *both
<mbj> just pushed the mutation covered buffer
<mbj> We shouldnt discuss style without dan
<mbj> Mostly because he agrees with mine more than I'm with yours ;)
<mbj> solnic: Pushed literal singleton emitters
<mbj> Beware that *looks* overdesigned, but it is not
<mbj> I just know what I do in this domain!
<mbj> This abstraction level is correct, more complex nodes to come
<mbj> Man, can someone do my client work. I'd love to finish that one today...
<mbj> It can also be argumented it is overkill to create an emitter instance per node
<mbj> We can easily optimize the instance away for trivial nodes later.
<mbj> But this design removes a lots of problems, it is the 4th generation of unparsers I write.
<mbj> BTW all mutations within SQL::Generator::Emitter can and should be killed via SQL::Generator::Emitter.visit
kleech has quit [Read error: Connection reset by peer]
<solnic> mbj: I trust you in 100% here so I just take everything you say for granted :P
<mbj> solnic: Can you follow the current implementation?
<solnic> mbj: re style, tell me what you disagree with me, would love to discuss
<mbj> solnic: not now
<mbj> solnic: Lets wait for dkubb here ;)
<solnic> mbj: I will go through this in about 15 minutes
<mbj> solnic: And to a council, we'll not end up in a schism.
<solnic> mbj: ain't gonna happen anytime soon, dkubb doesn't join the channel when I'm online
<mbj> solnic: We have to ping matt to make him join the channel ;)
<mbj> solnic: So I'll *try* to do boring clients code.
<solnic> mbj: hah I believe it's really up to him :)
<mbj> solnic: yeah, was more a joke
<solnic> mbj: I know :)
<solnic> mbj: but please do talk to me if you dislike something that I do
<solnic> I'm always happy to discuss
<mbj> solnic: So I'll try to do clients work. Parsing a weakly defined XML file into domain objects...
<mbj> solnic: It is mostly about do; end vs {} ;)
<solnic> I think we did many things great and some things, not so great ;P
<mbj> solnic: But pls dont start discussion now
<solnic> ok ok
<solnic> gotta do client stuff too
<mbj> solnic: Ping me on the emitter
<solnic> will do
<solnic> ttyl
<mbj> solnic: I can also add an unary node if you whant (negation) to make you "get" the whole picture
<mbj> Did not used any emitter base class method jet.
<solnic> mbj: sure
<mbj> solnic: going for lunch
snusnu1 has joined #rom-rb
<mbj> solnic: Post an update about rom here! https://twitter.com/datamapper
<mbj> snusnu1: hola
<solnic> mbj: I forgot the password and don't have it saved anywhere ;(
<solnic> AGAIN
<solnic> oh well
* mbj lulz
<mbj> solnic: Doesnt twitter has an su-mode, for operating "role" accounts.
<solnic> mbj: btw romrb is TAKEN on twitter
<solnic> how fucking terrible is that
<solnic> mbj: no, twitter sucks
<mbj> pff
<mbj> twitter is distributed furier transform
<mbj> We all filter the noise together via the follower tree
<mbj> s/tree/graph/
<mbj> That is okay, but yeah, it sucks.
<solnic> mbj: should I register "rom_rb" on twitter? O_o
<solnic> they don't even support - in handles geez
<mbj> solnic: Your decision, I still dont like twitter that much!
<solnic> mbj: http://railsgirlssummerofcode.org/campaign/ <== they raised > $50k
<mbj> Wow
<mbj> Nice!
<mbj> Look at their sponsors, all organizations that would benefit from rom ;)
<mbj> But we need a manager (NOT ME) for such a campaign.
<snusnu1> solnic: need the DM password?
<solnic> snusnu1: yeah we could tweet about ROM
<solnic> snusnu1: can you re-connect as snusnu?
snusnu1 has quit [Quit: Leaving.]
snusnu has joined #rom-rb
<snusnu> yo
<snusnu> solnic: got the pass?
<snusnu> mbj: need the pass too?
lorenzo has joined #rom-rb
<lorenzo> hi!
<mbj> lorenzo: hola
lorenzo is now known as Guest17519
Guest17519 is now known as lorenzoplanas
<lorenzoplanas> I'm trying to build a sample HTTP API using rom, but can't get pass installing the necessary gems properly
<lorenzoplanas> running that spec complains about not finding the Axiom::Adapter constant
<lorenzoplanas> it must be silly, I'd appreciate some insider knowledge :)
<snusnu> lorenzoplanas: have a look at what i require in https://github.com/snusnu/substation-demo/blob/master/demo.rb
<snusnu> lorenzoplanas: also, hey :)
<snusnu> lorenzoplanas: basically you're missing: https://github.com/snusnu/substation-demo/blob/master/demo.rb#L13-L15
<snusnu> s/missing/need
<snusnu> solnic: awesome
<lorenzoplanas> I see, thanks a lot!
<solnic> lorenzoplanas: be aware that we're splitting rom into rom-relation and rom-mapper
<solnic> and stuff will change
<solnic> initially we won't even support relationships :)
<lorenzoplanas> @solnic yep, that's ok
<solnic> I mean, no syntax sugar for relationships will be available initially
<lorenzoplanas> solnic: I'm used to building relationships on a method by method basis
<lorenzoplanas> solnic: I'm that weird :D
<lorenzoplanas> solnic: I'm eager to find a sane way to separate logic from persistence, hence my interest in virtus, rom, etc.
<solnic> lorenzoplanas: that's cool, you will be able to build joined relations but no auto-mapping will be available initially
<lorenzoplanas> solnic: oks!
<solnic> but it's easy to write your own mapper so that's not gonna be a huge issue if you want to get your hands dirty
<lorenzoplanas> solnic: definitely, I'm already getting my hands dirty with my own approaches, but those hardly scale to fellow devs' wetware
<lorenzoplanas> solnic: so I rather contribute what I can to rom
snusnu has quit [Quit: Leaving.]
<solnic> lorenzoplanas: that's cool!
<solnic> lorenzoplanas: with the rename we're cleaning a lot of stuff up so it's gonna be much easier to contribute soon
<solnic> it's such a gignatic piece of software that it takes time to organize all of that
<solnic> but we're really getting there :)
<lorenzoplanas> solnic: take your time, I'll probably need some to get my mind around all the new components in DM2
<lorenzoplanas> solnic: solving hard problems is hard :)
<solnic> lorenzoplanas: yeah, many people underestimate this
<solnic> it's a huge effort
<solnic> anyway, it'll pay off really soon
<solnic> once we get sql generator out we'll be able to wrap up rom-relation in no time
<solnic> later it's just adding mapping layer (still relatively easy)
<solnic> and session is going to be tricky but it won't be a major blocker (like sql is now)
<solnic> we kinda need sql to make shit work rite? :D
<lorenzoplanas> solnic: I suspect so :D
ptico has joined #rom-rb
<solnic> lunch bbiab
<mbj> lorenzoplanas: And as always feel free to ask any question
<mbj> ptico: hola!
<lorenzoplanas> mbj: thanks, will do!
<solnic> mbj: what's up with those utf-8 comments?
<solnic> CURLY_BRACKETS = IceNine.deep_freeze(%w({ })) <== really? O_o
<mbj> solnic: do you prefer CURLY_BRACKES = ['{'.freez, '}'.freeze].freeze ?
<solnic> no, I prefer not to freeze to be honest
<mbj> solnic: Mehh
<solnic> because why?
<mbj> solnic: I like rubies mutability until my app is fully loaded.
<solnic> are you afraid that some code in your library will try to change your constants?
<mbj> I'd love to have a Kernel.remove_all_performance_limiting_monkey_patch_support
<mbj> Once my app is fully loaded.
<mbj> solnic: Exactly
<mbj> solnic: Deeply frozen constants saved me more than freezing costs.
<solnic> really?
<mbj> Jo
<solnic> when?
<mbj> I write buggy code without noticing
<solnic> to change a constant you need to write a pretty explicit code
<mbj> For example doing a gsub! on a string, without noticing this string came from a constant
<mbj> No
<mbj> def foo(str)
<mbj> str.gsub!(foo, bar)
<mbj> end
<mbj> foo(Some::Random::CONSTANT)
<mbj> Maybe through indirection.
<mbj> def bar(str)
<mbj> foo(str)
<mbj> end
<mbj> Add some layers and you save time.
<mbj> I'd prefer ruby would ship immutable strings
<mbj> I already thought about adding ImmutableString
<solnic> well, ok
<mbj> It does not blow off anymore, but imagine a less skilled developer does ugly things
<mbj> I do lots of training sessions with locals
<solnic> lemme refactor this a bit
<mbj> And I like to define sharp interfaces even Some::Random::CONSTANT is an interface.
<mbj> self.class::CONSTANT is a nice pattern.
<mbj> you plan to mess with the emitter?
<solnic> mbj: just did
<solnic> a little
<solnic> nothing major
<solnic> just cleaned up stuff I didn't like
<mbj> haha
<mbj> I dislike reek compaining about duplication
<mbj> That constant thing is nice.
<mbj> We need a convention for naming frozen tokens
<mbj> K_ -> keyword
<mbj> D_ -> delimiter ?
<mbj> But changing this goes so fast. So I just let it grow and refactor later.
<solnic> mbj: reek can go to hell with this
<solnic> it's silly
<solnic> besides if you don't want to call attr reader twice, just use the @ivar
<mbj> solnic: I love using no ivars
<mbj> solnic: Because methods blow up if they dont exist
<mbj> ivars not
<mbj> ivars blow up one step later when calling method on nil
<solnic> true
<mbj> solnic: See my comment, I'll not do the lvar caching anymore.
<mbj> solnic: To sync our styles a bit, now you have to give up your {} vs do; end rules ;)
<solnic> yes, I did this just for you :D
<mbj> solnic: Mine is very simple, use {} for single line, do end for multiline
<mbj> hahahaha
<mbj> solnic: thx!
<solnic> dup calls are ~0.000002 slower
<solnic> OH NOEZ
<mbj> solnic: I'm not doing this for performance!
ptico has quit [Remote host closed the connection]
<mbj> For using least amount of complex nodes.
<mbj> send is more complex than lvar access.
<mbj> As I said, I'll give up this rule.
<solnic> ok man, moving on
<mbj> Only reducing number of nodes from now.
<solnic> re constant names
<solnic> I like it
<solnic> I mean, the short versions
<solnic> long contant names suck
<mbj> Depends.
<solnic> and you can quickly learn what those abbreviations mean
<solnic> so CB_L sounds nice to me
<mbj> It is okay if you have zillions of constants, like the ones here.
<solnic> yup
<solnic> I'm talking about SQL project specifically
ptico has joined #rom-rb
<mbj> sync
<mbj> solnic: BTW what about using mutant for complexity measurement.
<mbj> solnic: Amount of mutations (killed or not) == best complexity metric (IMHO)
<solnic> mbj: yes it's an interesting way of thinking about complexity
<solnic> but it makes total sense
<solnic> s/but/and/g
kalleth_ has joined #rom-rb
<kalleth_> ;D
<solnic> kalleth_: :)
<kalleth_> i am going to go watch star trek
<kalleth_> so i will see you in a couple of hours
<solnic> kalleth_: enjoy
mbj has quit [Quit: Lost terminal]
mbj has joined #rom-rb
<mbj> A hard yakuake crash messed up my X.
<solnic> mbj: shit man you're on KDE?
<solnic> or just using yakuake under other DE?
<solnic> mbj: is your editor configured to display whitespaces? I noticed you're leaving whitespaces in some places
<mbj> nope my editor is not configured to display dangling whitespaces
<mbj> Forgot that setup
<mbj> Nope, I'm on fluxbox
<mbj> no icons, no grapical nosthing.
<mbj> No menues (or I dont use them).
<mbj> But yakuake is the best "type button and you see it full screen" window manager I found
<mbj> s/type/hit/
<mbj> There is a single line I have to add to my vimrc
<solnic> mbj: OK
<mbj> but I dunno wich one, have to look it up
<mbj> but *busy* ;)
knowtheory has joined #rom-rb
<solnic> mbj: set list listchars=tab:»\ ,trail:·,nbsp:·
<mbj> solnic: works perfectly, thx!
<mbj> solnic: Better than my solution!
<solnic> mbj: sure :)
<solnic> mbj: I'm gonna add missing literals
<solnic> mbj: why those classes are below "private" keyboard?
<mbj> solnic: To make the def dispatch private.
<solnic> but you put nested classes below that keyword too
<solnic> looks weird
<mbj> solnic: show me
<mbj> singleton.rb ?
<solnic> yes
<solnic> D_QUOTE = %q(').freeze <= why %q?
stormwin1 has joined #rom-rb
ddfreyne has quit [Excess Flood]
<mbj> solnic: I dislike "'"
ddfreyne has joined #rom-rb
<solnic> oh :)
<solnic> fair enough
<solnic> mbj: we could rename it to D_SINGLE_QUOTE
<solnic> and add D_DOUBLE_QUOTE
<mbj> solnic: do so
lorenzoplanas has quit [Ping timeout: 264 seconds]
stormwind has quit [Ping timeout: 264 seconds]
snusnu has joined #rom-rb
lorenzoplanas has joined #rom-rb
<solnic> so if I get that correctly we need separate classes for emitting those literals
<solnic> rite?
<solnic> all of them
<mbj> no
<mbj> You can also handle multiple types in one class
<mbj> def dispatch
<mbj> write(TYPES.fetch(node.type))
<mbj> end
<mbj> TYPES = { :true => K_TRUE, ... }
<mbj> If you like it this way.
<mbj> handle :true, :false, :null
<mbj> I have some emitters in unparser that handle multiple nodes
zekefast has joined #rom-rb
<mbj> This way it would look cleaner.
<mbj> let me change it
<mbj> solnic: done
<mbj> zekefast: hola!
<solnic> SingleQuote < Singleton etc?
<solnic> or are those separate classes needed only for keywords?
solnic has quit [Excess Flood]
<zekefast> Hi
solnic has joined #rom-rb
<solnic> mbj, snusnu: ^^ this is awesome
<mbj> solnic: no
<solnic> mbj: no what?
<mbj> solnic: You dont get the point, you should not have an emitter that emits a single SingleQuote ;)
<mbj> solnic: There arent any more singleton literals anymore.
<mbj> solnic: You have to start with strings.
<mbj> solnic: s(:string, "foo") is the node
<mbj> handle :string
<mbj> def dispatch
<mbj> write(quote(first_child))
<mbj> end
<mbj> And inside Emiter::Literal::String there is a private quote using the constant ;)
<solnic> mbj: so I need to add Literal::String
<solnic> that can handle :single_quote and :double_quote
<solnic> rite?
<mbj> solnic: We'll not have a :single_quote node.
<mbj> We'll have a node that represents a literal string.
<solnic> ok gotcha
<mbj> but without the details how this is done in the actual syntax.
<mbj> Hence: AST - ABSTRACT - Syntax - Tree
mbj_ has joined #rom-rb
<mbj_> Sorry DSL reconnect...
<mbj_> (ADSL)
<mbj_> Some nodes have multiple children, some one, some none.
<mbj_> true is AST::Node.new(:true, []) internally
<mbj_> For that reason I call it "singleton". Because there is no information to distinguish between to TRUE within SQL.
<mbj_> SELECT * FROM groups, is s(:select, :all_fields, s(:identifier, "groups"))
<mbj_> No need for that FROM, you always have a from if the 2nd child is present.
<mbj_> SELECT 1+1, s(:select, s(:add, s(:int, 1), s(:int, 1))
<mbj_> snusnu: Get the point?
<mbj_> For that reason we have the AST_FORMAT.md
<mbj_> Where we define how SQL strings are mapped to AST
<solnic> gotcha
<mbj_> The AST should contain all information to reproduce an equivalent, but not similar ast.
<mbj_> If you write SELECT 1+1, or SELECT\n1+1
<mbj_> The AST looks the same.
mbj has quit [Ping timeout: 245 seconds]
mbj_ is now known as mbj
<mbj> So you only have information in the ast carring semantics.
<mbj> Pls update AST_FORMAT.md with all changes you do, so I can review it.
<solnic> mbj: I don't make any changes
<solnic> I don't know how :P
<mbj> Why, just document
<mbj> strings?
<solnic> mbj: trying to get that working
<mbj> it should be something like:
<mbj> def dispatch
<solnic> mbj: ok I think it works
<solnic> at least my spec passes
<mbj> write(QUOTE, first_child.gsub(QUOTE, ESCAPED_QUOTE), QUOTE)
<solnic> mbj: just pushed
<solnic> mbj: I took code from axiom sql generator
<mbj> np
<solnic> I can make it like you wrote
<mbj> just remove that Emitter prefix for constant lookup
<solnic> what's better?
<mbj> I'd use mine
<solnic> looks nicer yeah :)
<solnic> lemme refactor
<mbj> Mostly because #quote does not depends on the instance.
<mbj> write takes multiple arguments
<mbj> why dont u use the assert_generates node, expectation helper?
<mbj> assert_generates s(:string, %q(echo 'hello world')), %q(.... )
<mbj> BTW covering whole sql ist just like this, start from singleton literals
<mbj> than primitive literals
<mbj> than composed literals (array etc, we dont have them here)
<mbj> than go to unary nodes, negation and friends
<mbj> than binary
<mbj> assert_generates s(:not, s(:true)), '!TRUE'
<solnic> ok
<solnic> mbj: I'm gonna help you with this
<solnic> as you can see, I'm slow because I'm clueless
<solnic> but I'll get there quick
<mbj> It is *boring* work.
<solnic> kinda, that's why I want to help
<mbj> BTW I'd emit s(:not, s(:true)) as '!(TRUE)'
<solnic> esp that I can learn new stuff
<solnic> looks like we've got some stuff for free from ast gem
<solnic> so it could've been worse :)
<mbj> So put parentheses *everyhwere*
<mbj> To make sure we dont have to track context in early versions.
<mbj> Beautify leater!
<solnic> yeah it's probably a good idea
<mbj> s(:not, s(:and, s(:true), s(:true))) would get emitted as !(TRUE & TRUE)
<mbj> I'd always put parentheses at the *parent* not at the child.
<mbj> Lesson learned from doing this a lot ;)
<solnic> :)
<solnic> brb need a snack
* mbj needs a coffee
<mbj> solnic: Do you see how clean the code becomes with this emitter design?
<solnic> mbj: yeah it's nice encapsulation
<solnic> coverage 0% wtf
<mbj> solnic: Ignore that one
<mbj> solnic: Mutant is the only tool ;)
<solnic> dude
<solnic> build fails because of that
<solnic> annoying
<mbj> So run the metrics locally and fix?
<solnic> mbj: it reports 0%
<solnic> simplecov
<solnic> not that online coverage thing
<solnic> so the build fails
<mbj> most likely a config issue
<solnic> ok got it
<solnic> fixing
<solnic> pushing
<solnic> mbj: I'll add missing specs
<mbj> solnic: It is really nice you get that style.
<mbj> It is the 4th generation, and I really like it. Especially as adding context tracking is easy. I need this for a perfect "ruby prettifier".
<solnic> :)
<solnic> mbj: looks like I can't get 100% now
<solnic> mbj: since we don't use all of the emitter methods yet (private ones)
<mbj> solnic: Yeah
<mbj> solnic: I removed all but the emitter methods I think we need
<mbj> solnic: Feel free to remove them and pull them back in. Or write emitters for more nodes.
<mbj> Most are helpers for more complex nodes!
<solnic> mbj: I want to quickly add more emitters
<solnic> tell me what's next
<solnic> and I'll do it
<solnic> food, bbiab
<mbj> solnic: Cover all literals
<mbj> float, integer
<mbj> at least
<mbj> Than add unary operators, minus, plus, negation etc.
<mbj> Also identifiers!
<mbj> s(:identifier, "foo") => %q(foo)
<mbj> s(:identifier, "foo'") => %q("foo'")
<mbj> forget, lets emit identifier always double quoted.
<mbj> Dont optimize now.
<mbj> s(:idnetifier, "foo") => %q("foo")
<mbj> s(:identifier, %q(f"oo) => %q("fo""oo")
<mbj> Than go to scalar binary operators, boolean operators etc
<mbj> Once you have this you can IMHO do a select statement
<mbj> nope
<mbj> First add type nodes.
<snusnu> all this %q() stuff looks awful, as does the do..end
<snusnu> :p
hryk has joined #rom-rb
* mbj needs dkubb in this channel to do the style discussion
<snusnu> hrhr
<mbj> solnic: I'd really dislike to parse '"fo""oo"' %q() makes it ultra obvious quotes are in as is.
<snusnu> mbj: i was just trolling wrt %q()
<snusnu> mbj: i've read your arguments before
<solnic> snusnu: what do/end?
<snusnu> mbj: so while i still think it looks awful, i completely understand the motivation
<solnic> my vim nicely highlights "'" in a way that makes it readible
<solnic> fwiw...
<snusnu> solnic: oh, i just threw do..end into the mix cause i know mbj likes to talk about it :o
<solnic> lol
<snusnu> solnic: mine too
<solnic> I thought so actually
* mbj needs dkubb in this channel to do the style discussion. And hopes we can skip it for now.
<snusnu> aww
<snusnu> hehe
<mbj> solnic: Your trailing whitespace config made me fix lots of stuff in private projects already, nice!
<mbj> I always discover new features in vim!
<solnic> mbj: sure :)
<snusnu> mbj: my vim automatically strips trailing ws
<snusnu> on save
<snusnu> i don't see the ws chars
<solnic> snusnu: gotta steal that from you
<snusnu> lemme check
<mbj> snusnu: Yeah pls publish!
<solnic> mbj: ok so re integer/float
<solnic> how where?
<solnic> :D
<mbj> solnic: just as with string, convert an ruby fixnum to a string that could be read by sql engines?
<mbj> class Integer
<mbj> def dispatch
<solnic> mbj: so Integer and Float classes
<solnic> rite
<mbj> write(first_child.to_s)
<solnic> yeah sure
<mbj> solnic: I said this is super easy....
<mbj> We *can* add some filtering later.
<mbj> So for example the SQL standard will most likely not cover rubies bignums.
<solnic> mbj: s(:integer, 1) ?
<mbj> solnic: yeah
<solnic> s(:float, 1.0)?
<solnic> ok ok
<solnic> gotcha
<mbj> solnic: Always use ruby primitive if possible.
<mbj> solnic: Literals are easy
<mbj> solnic: You remember how fast I was with aql gem? And this one was not even backed by that nice ast strucuture
<mbj> I did an RBX style ast with some optimizations.
<snusnu> i have no idea if it is elegant or whatever, i found it somewhere and it works
<snusnu> sometimes i need to add new file types
<mbj> snusnu: thx, worksforme
<mbj> my .vimrc looks like my first programming spagetty over the time...
<ptico> Hi all, mbj asks me for a commercial feedback
<ptico> for mutant
<mbj> * using mutant on commercial projects ;)
<mbj> Hopefully you are not selling it :D
<ptico> mbj: yeah, thanks
<ptico> no, my name is not Egor Homyakov
<ptico> :)
<mbj> dont know this story?
<solnic> mbj: ok done what's next?
<ptico> No, i know only about Rails bug
<ptico> so, i want to cover only some critical parts, which is logical, because covering *all* the application will cost a lot
<mbj> ptico: Is the critical part in a specific namespace?
<mbj> solnic: You did float and fixnum?
<ptico> Question: It's possible to have a list of specs/objects to test?
<solnic> mbj: float and integer, yes
<mbj> yeah
<mbj> solnic: unary minus, and plus
<ptico> mbj: no, it's some repositories and service objects
<mbj> solnic: now we have a decision point on how to structure the inheritance tree to save us code
<mbj> ptico: Okay, where is your question?
<mbj> solnic: We could add an "unary" namespace
<mbj> solnic: Emitter::Unary::{Here,The,Drangons}
<mbj> solnic: But I dislike to design these proactively
<mbj> solnic: Just add Emitter::UnaryMinus, UnaryPlus, Not
<mbj> solnic: Than we'll see the duplication and decide?
<ptico> mbj: how can i test only objects i want without running number of parallel mutant commands?
<ptico> mbj: maybe something like .mutant.yml
<mbj> ptico: without parallel => a specific object ?
<mbj> ptico: Mutant 0.2 has some design limitiations on cherry picking classes/methods to cover.
<mbj> ptico: Does not support fine grained configuration currently
<solnic> ptico: I would suggest not using dm2-rspec style for mutant, it may lead to a lot of duplicated or too brittle tests
<solnic> fwiw it's gonna be improved in future version of mutant (according to mbj)
<mbj> yeah
<mbj> We'll have "kill expressions" that you can use to delegate a mutation kill to a specific spec
<solnic> there was always something that bugged me with mutation testing with heckle
<ptico> mbj: ok, thanks
<solnic> now I now what it was
<solnic> :)
<solnic> s/now/know/
<mbj> ptico: But there are workarounds possible
zekefast has quit [Ping timeout: 245 seconds]
<mbj> ptico: So tell me more about your case!
<solnic> mbj: ok more food, bbiab
<mbj> solnic: yeah, ate an apple and ran for new coffee already
<ptico> mbj: rails application, some important service/use-case objects, i cover it with mutant, but don't want to touch another ~1000 examples
<mbj> ptico: Can you enumerate the objects as ::Foo::Bar, ::Foo::Baz?
<ptico> mbj: yes
<mbj> mom
<mbj> ptico: You want to replace the metrics:mutant task with the more "narrow" version?
<ptico> mbj: exactly)
<mbj> ptico: sorry, mom
<mbj> ptico: updated
<mbj> ptico: I'd suggest you still use --rspec-dm2 especially as you whitelist the objects.
<ptico> mbj: thanks! that's what i want
<mbj> ptico: Remember, mutant will "recurse" into the namespace. So if you have Foo::Bar::Baz, and specifiy Foo::Bar, it will also mutant Foo::Bar::Baz. I fixed this in master already.
<mbj> For recursion you need to specifiy ::Foo::Bar** ;)
<ptico> mbj: great
<mbj> ptico: So if you have the situration you whant ::Foo::Bar, but not ::Foo::Bar::Baz you need to specifiy the methods like ::Foo::Bar#{a,b,c} etc.
<ptico> mbj: btw, i'm ok with --rspec-dm2, shared contexts helps me to keep it clean
<mbj> ptico: Yeah, but sometimes it is ugly, I'll provide overrides in future. And I think we'll have a .mutant.yml ;) But I'd like a .mutant.rb more, because you maybe whant to add specific logic. dunno will explore.
<mbj> ptico: Thx for feedback! And let it come!
<solnic> mbj: hmm what'd be the spec for unary plus? s(:+, '2') # => '+2'?
<mbj> solnic: no, dont use symbolic symbols
<solnic> ugh yeah that was just a shortcut here
<mbj> s(:uplus, argument)
<mbj> s(:uplus, s(:int, 2))
<mbj> s(:uminus, s(:float, 3.0))
<mbj> So you do
<mbj> def dispatch
<mbj> write(operator); visit(first_child)
<mbj> end
<solnic> rite
<solnic> I wasn't sure about that visit(first_chid)
<solnic> rite
<solnic> thanks
<mbj> And you can try to collapse these into a single scalar unary node if you like
<mbj> use a table again ;)
<mbj> write(TABLE.fetch(node.type)); vvisit(first_child)
<mbj> and register all unary scalars...
<mbj> We should have nice constants such as O_PLUS, O_MINIS
<solnic> mbj: how would you name it?
<mbj> Unary::Scalar ?
<mbj> UnaryScalar ?
<mbj> I typically discover naming and inhertance over the time.
<mbj> Cannot say something definitive.
<solnic> UnaryScalar
<solnic> roger that
<mbj> solnic: BTW you did a mistake above s(:+, '2') that 2 should be a node again. Else it cannot get visited.
<solnic> ok
<mbj> solnic: Just to finally get this fixed in your brain.
<mbj> As leaves of the tree there are only nodes that do not visit other nodes anymroe.
<solnic> rite
<mbj> So an unary node as plus will not have a pritmive child, the child MUST be a node itself.
<mbj> When you dig some of my code, you see lots of Unary, Nullary and Nary
<mbj> Ducktrap is build on it.
<mbj> An Unary ducktrap delegets to antoher ducktrap, exactly one
<mbj> Nullary does not delegate to another ducktrap
<mbj> and Nary to many ducktraps.
<mbj> Nullary still takes arugments (the input) but does not delegate anymore.
<mbj> For me it is really simple to visiualize this way.
<mbj> my spelling degenerated
<solnic> ok so it basically adds the operator to the buffer and visits the first child
<mbj> Yeah
<mbj> For example binary operators wil visit left, write operator, visit right
<mbj> This is nothing more than an recursive tree walker with def visit_uminis(node, buffer)
<mbj> s/uminis/uminus/
<mbj> Just added indirection via "handling types" and you get a context (emitter instance) for prettifying code.
<mbj> Maybe it turns out this is over design for sql, dunno for ruby it was really nice.
<mbj> For unparser I'll also condense some classes thogether with the TABLE trick.
<solnic> mbj: ok added +,- and negation
<mbj> solnic: nice!
<mbj> solnic: So IMHO we should emit unary node child within parentheses
<solnic> mbj: ok
<solnic> mbj: lemme do it now
<solnic> we want !(TRUE)
<mbj> solnic: So once we have binary operators we dont end up in s(:uminus, s(:addition, s(:int, 1), s(:int, 1))) being emitted as: -1 + 1
<mbj> -(1+1) is the target
<mbj> solnic: Use parentheses { visit(first_child) }
<mbj> solnic: Base class helper method!
<solnic> yup :)
<solnic> I saw that because it was not covered yet
<mbj> should improve coverage a bit
<solnic> it will be in a second
<solnic> exactly
<mbj> Really nice, basically you dont need my help.
<mbj> we'll probably rename some of the type symbols over the time.
<mbj> Typically I dont abbreviate the class names, but the types.
<solnic> mbj: M_PO?
<solnic> M_PC?
<solnic> I can only figure out what "P" means there :)
<mbj> Parenthese
<mbj> Rename ;)
<mbj> PO parens open
<mbj> PC parens close
<solnic> hmm
<solnic> ok
<solnic> left/right is better imho
<solnic> agreed?
<mbj> yeah
<solnic> and "M"?
<mbj> just do, I dont have a preference here.
<mbj> Forgot...
<solnic> LOL :)
<solnic> it was something cool for sure
<solnic> :)
<mbj> haha
<mbj> Once you finished, I thin we can add Identifier
<mbj> I'd place it under Emitter namespace not Emitter::Literal
<mbj> BTW if you compare axiom-sql-generator::SQL::Generator::** and SQL::Generator::Emitter** you should IMHO feel
<mbj> the ast based approach simplifies a lot
<mbj> We dont have "helper metohods that dont touch instance" all the time
<mbj> Also we emit into a buffer, and do not concatenate over and over again.
<mbj> I do not blame dkubb for this design, he did the first generation and I had the chance to improve it.
<mbj> Also I was doing to_source before, without that experience I'd never had the idea of using a separate gem as intermediate (aql)
<solnic> mbj: yeah man, we're all learning :)
<solnic> also it was easy to fool yourself that axiom ast is all you need
<solnic> but nope
<solnic> mbj: ok what's next? binary ops?
<mbj> identifier
<mbj> Lets finish the needed boring ones ;)
<mbj> Than we'll do boolean binaries connective, disjunction
<mbj> s(:and, left , right)
<mbj> s(:or, left, right) where left and right are nodes ;)
<elskwid> Greetings all.
<solnic> mbj: https://www.gittip.com/for/ruby/ <== see top receivers :D
<solnic> elskwid: oh hai
<elskwid> (I almost called you Romulans)
<solnic> elskwid: LOL
<mbj> The boring fact is, you do that stuff I should do. It takes more time to guide you than do this for myself.
<mbj> But I hope this changes soon :D
<mbj> This is not blaming you! It is normal it takes time till the message sinks in.
zekefast has joined #rom-rb
<mbj> elskwid: hola
<mbj> solnic: And yeah, nice you made it there!
<elskwid> Hi solnic , Hi mbj
<elskwid> You guys are rockin' that AST
<solnic> mbj: I warned you alright
<mbj> solnic: haha
<solnic> mbj: also, it's bad only you and dkubb could do this stuff
<mbj> solnic: You can already do it, you dont trust yourself here.
<solnic> mbj: no I don't
<solnic> elskwid: really? I feel like I've spent entire day doing something that should take 15 minutes lol
<mbj> solnic: That is the point where I normaly move to a pice of paper and convince person I'm helping he knows all that stuff already.
<solnic> mbj: ok so identifiers
<elskwid> solnic: Ha ha.
<elskwid> I'll let you guys get back to it. solnic, when you get a chance take a look at that PR. It feels pretty good to me. When it's merged assign me the next one! (I would suggest a spec update to the new syntax perhaps)
<elskwid> I'm going to go run before the heat.
<mbj> solnic: s(:ident, "foo") => %q("foo")
<solnic> elskwid: ok I will merge it in!
<mbj> solnic: s(:ident, "fo\"") => %q("foo""")
<mbj> solnic: IMHO s(:id) is best!
<solnic> mbj: yeah I like short
<solnic> names
<mbj> solnic: We'll have to call that s() macro often ;)
<solnic> mbj: what's the diff between id and string?
<mbj> solnic: SELECT * FROM "foo" <- This is the identifer
<mbj> not a normal string
<mbj> identifiers get quited with double quotes
<mbj> strings with single quotes.
<solnic> rite
<mbj> solnic: After that I'd say we can create asingle class that handles ALL binary operators, scalar and boolean.
<mbj> solnic: IMHO, as far as I remember SQL.
<mbj> solnic: Than we should add "attributes", nothing more than scoped identifiers.
<mbj> SELECT foo.bar <- attribute
<mbj> s(:attr, s(:identifier, "foo"), "bar")
<mbj> These can also be nested, foo.bar.baz
<mbj> s(:attr, s(:attr, s(:identifier, "foo"), "bar"), "baz")
lorenzoplanas has quit [Ping timeout: 276 seconds]
dkubb has joined #rom-rb
<mbj> dkubb: hola!
<mbj> dkubb: Nice to see you here!
ptico has quit [Remote host closed the connection]
<dkubb> hello
<dkubb> wow, you and solnic did a bunch of stuff on sql last night
<mbj> dkubb: TBH we are slow.
<mbj> Helping solnic to join the AST camp ;)
<mbj> We are porting the unparser design, and he already fixed some sharp edges I'll have to backport to unparser. Win-win.
lorenzoplanas has joined #rom-rb
<dkubb> mbj: how did changing that unit test timeout to use the real time help?
<mbj> dkubb: We did not do it.
<dkubb> mbj: I noticed you bumped the timeout in sql to 1 sec. that seems really high for a unit test, so I wondered if it didn't help
<dkubb> mbj: ahh ok, then maybe I can do that tonight
<mbj> dkubb: I think indrekj did not pushed his changes.
<mbj> dkubb: I basically deactivated it with that "1s" config.
<mbj> Because I'm on a very old 2009 notebook and the disc is slow.
<dkubb> yeah, it would be nice to get the realtime so we wouldn't need to deactivate it
<dkubb> ahh
<mbj> Tomorrow I'll be on a Lenovo 530W with 32Gig of ram, and an SSD ;)
<mbj> Than we can lower it a bit :D
<snusnu> mbj: btw, iirc it was cored who was working on the timeout patch
<mbj> snusnu: yeah, sorry.
<mbj> snusnu: Indrekj did the awesome inflecto cleanup!
<snusnu> yup
<mbj> They *still* did not released their super dupa, deep hash params based elasticsearch driver...
<mbj> I'm curios why my design was bad in their opinion. I'll nitpick a lot on the code. (Mutant will help to identify valid targets).
<snusnu> lols
<solnic> dkubb: morning
<dkubb> solnic: good morning
<solnic> mbj: FYI "dupa" means "ass" in polish :D
<dkubb> solnic: you guys did a ton of nice stuff while I was asleep
<solnic> dkubb: yes, kinda, I'm learning so it's going slow
<solnic> mbj: just pushed identifier
<mbj> haah
<dkubb> mbj: for stuff like K_TRUE, K_FALSE, etc, should those be moved into the literal emitter, or do you prefer those constants in the emitter.rb ?
<dkubb> I mean moved to literal/singleton.rb
<solnic> I don't think I like those class methods on Emitter
<solnic> wdyt about adding an emitter registry object
<mbj> dkubb: Some constants will be reused.
<mbj> dkubb: But that is not so common in sql as in ruby.
<solnic> mbj: ok buddy what's next?
<mbj> dkubb: BTW a list of all keywords is *always* handy
<mbj> dkubb: We need it later if we prettify identifiers.
<mbj> s(:id, "TRUE") => "TRUE", where s(:id => "foo") => foo
<mbj> solnic: binary operators, scalar and boolean
<mbj> solnic: We dont have all literals, but I think we should do some more strucutral nodes now.
<mbj> Because they are more fun.
<mbj> solnic: s(:and, s(:true), s(:false)) => 'TRUE AND FALSE'
<mbj> def dispatch; visit(left); write(WS, TABLE.fetch(node.type), WS); visit(right); end
<mbj> where left and right are children[0] and children[1]
<mbj> I'd to a multiple assignment like left, right = children
<solnic> mbj: ok cool
<mbj> solnic: than we have to "Fix" nested binaries
<mbj> solnic: s(:and, s(:and, left, right), right2) => (left and right) and right2
<mbj> And because this would be stupid to implement (inspecting the child for need of parentheses I'd say we wrap both, left and right in parentheses.
<mbj> so:
<mbj> s(:and, left, right) => (left) and (right)
<mbj> My rule is to only wrap childs, never wrap self. This way we at least dont have an unnneded outer parenthese pair.
<mbj> We can optimize later, but it is okay for generated code to be very explicit, maybe we'll also solve remove some precendence bugs in implementations.
<dkubb> mbj: at some point we'll probably want to do some inspection of the child to only wrap when necessary.. but for now what you're proposing is safer
<mbj> dkubb: yeah
<mbj> dkubb: We'll prettify once we can round trip.
<mbj> dkubb: Also it reduces lots of complexity with explicit parentheses.
<mbj> dkubb: I plan not the child can tell if it has a high or low precedence in relation to parent. So we can create a reusable visit_at_precedence(child)
<mbj> dkubb: This would query the child and wrap inside parens if needed.
<mbj> s/plan not/plan/ sorry
<mbj> dkubb: Or we just patch #visit to do this. and remove all parentheses { visit(some_child) } calls.
ddfreyne has quit [Excess Flood]
ddfreyne has joined #rom-rb
kapowaz has quit [Read error: Operation timed out]
<solnic> back
<solnic> mbj: Emitter::BinaryOperation?
<mbj> solnic: jo, we can rename later
<mbj> solnic: def dispatch; parentheses { visit(left) }; ...; parentheses { visit(right) }
stormwin1 has quit [Ping timeout: 246 seconds]
kalleth_ has quit [Quit: No Ping reply in 180 seconds.]
kapowaz has joined #rom-rb
kalleth has joined #rom-rb
<dkubb> bbl, gotta start work
dkubb has quit [Quit: Linkinus - http://linkinus.com]
lorenzoplanas has quit [Quit: WeeChat 0.4.0]
<solnic> mbj: binary op is in
<mbj> solnic: yeah
<mbj> solnic: add OR, +, -, * and the other scalars
<mbj> solnic: via the table
<mbj> solnic: Or do you whant to do more structural stuff?
<mbj> I need to gsub my brain on whant to want soon...
<solnic> mbj: no pref here
<solnic> just want to push it forward
<solnic> also, gotta do some client work now and help with the baby
<solnic> so bbiab
<mbj> solnic: yeah
hryk has quit [Quit: hryk]
postmodern has joined #rom-rb
postmodern has quit [Quit: Leaving]
<elskwid> Busy busy busy
djsell has joined #rom-rb
stormwind has joined #rom-rb
<snusnu> yo mbj
<snusnu> mbj: do we actually only want to ignore calls with explicit self as the receiver, or implicit self receiver too?
mbj has quit [Ping timeout: 245 seconds]
snusnu has quit [Quit: Leaving.]
snusnu1 has joined #rom-rb
knowtheory has quit [Quit: Get MacIrssi - http://www.sysctl.co.uk/projects/macirssi/]
mbj has joined #rom-rb
knowtheory has joined #rom-rb
<mbj> solnic: We should use longer type names
<mbj> solnic: That table is enormous and we need a reference: http://savage.net.au/SQL/sql-2003-2.bnf.html#period
<mbj> solnic: Took 1 min to render on my machine
<snusnu1> mbj: imo your suggestion re the reek warning doesn't make much sense
<snusnu1> wrrgh
snusnu1 has quit [Quit: Leaving.]
snusnu has joined #rom-rb
<snusnu> mbj: why only explicit self?
<mbj> snusnu: ?
<mbj> snusnu: Warn on explicit self, do not warn on implicit self.
<mbj> snusnu: because explicit self duplication is a smell
<snusnu> yeah, why?
<mbj> and implicit is not.
<snusnu> i see no difference?
<mbj> snusnu: When you have to use an explicit self twice you most likely whant to create a local variable with the same name.
<mbj> But when you have a local variable a second call to self does not really make sense!
<mbj> def foo
<mbj> bar = self.bar # okay
<mbj> def foo
<mbj> bar = self.bar
<mbj> self.bar.baz # smell
<mbj> end
<snusnu> i don't see how that's any different from using implicit self .. apart from the possibility to name the lvar the same as the method
<mbj> it produces differend bytecode
<mbj> Also there should not be a need for excplitcit self, only to overcome shadowing
<mbj> snusnu: If you odo self.foo, followed by self.bar this will not trigger
solnic has quit [Quit: Leaving...]
solnic has joined #rom-rb
<snusnu> mbj: the reek integration cucumber features want it to report duplicate method call for: puts(@s.title)
<snusnu> mbj: imo that's wrong
<snusnu> mbj: it should complain about @s.title
<snusnu> mbj: there's really nothing wrong with calling a method (especially one like puts) with the same argument more than once?
<snusnu> mbj: or maybe i'm just crazy after trying to read reek code plus grokking the sexps
solnic has quit [Ping timeout: 248 seconds]
<snusnu> mbj: btw, looks like rubocop functionality is nowhere near to reek's
<mbj> snusnu: okay
<mbj> snusnu: ruby_parser sexps are stupid
<snusnu> mbj: the reason i was initially asking if we want to only warn on methods with no parameters kinda came from me not knowing how to work around that integration spec issue
<snusnu> mbj: but tbh, i'm not interested in writing that patch anymore
<snusnu> mbj: if you know how to quickly do it, here's the relevant file: https://github.com/troessner/reek/blob/master/lib/reek/smells/duplicate_method_call.rb
<snusnu> mbj: i found no immediate way to make it pass the cukes .. basically i just added: next if call_node[1].nil? below https://github.com/troessner/reek/blob/master/lib/reek/smells/duplicate_method_call.rb#L75
<snusnu> mbj: and i added a passing unit test for that
<snusnu> mbj: but as i said, the cukes made me quit
<snusnu> mbj: for one, because i can't stand the output, lol
<mbj> snusnu: I'm to "müde"
<mbj> no chance now.
<mbj> goging to sleep
<mbj> cu
mbj has quit [Quit: leaving]
pdswan has joined #rom-rb
<zekefast> Hi, guys. I'm eager to try ROM, but after moving tom ROM from DataMapper2 all previous examples seems like stop working.
<zekefast> Have you any idea when it would make sense come back and try somekind "stabilized" version?
<zekefast> At least get to work mappers again.