ChanServ changed the topic of #picolisp to: PicoLisp language | Channel Log: https://irclog.whitequark.org/picolisp/ | Check also http://www.picolisp.com for more information
rick42 has quit [Quit: ZNC - http://znc.in]
rick42 has joined #picolisp
ubLIX has quit [Quit: ubLIX]
orivej has joined #picolisp
xkapastel has quit [Quit: Connection closed for inactivity]
freemint has quit [Ping timeout: 264 seconds]
mtsd has joined #picolisp
orivej has quit [Ping timeout: 240 seconds]
orivej has joined #picolisp
rob_w has joined #picolisp
Regenaxer has left #picolisp [#picolisp]
Regenaxer has joined #picolisp
ubLIX has joined #picolisp
freemint has joined #picolisp
<freemint> Good Morning
<freemint> Regenaxer, i figured out how to n-to-m relations. it was easier than i thought.
<freemint> It was in general easier then i thought.
<mtsd> Good morning freemint
<freemint> Good morning
<freemint> I also wrote a "introductory database scheme" whihc contains most things that make the pilDB cool. https://pastebin.com/2CDZZ23b any comments?
inara has quit [Quit: Leaving]
<freemint> I have not tested everything yet
inara has joined #picolisp
inara has quit [Remote host closed the connection]
ubLIX has quit [Quit: ubLIX]
inara has joined #picolisp
<freemint> mtsd, hos are you?
xkapastel has joined #picolisp
<freemint> (select +Player nm "Jasper") finds an object in an +SN +Idx but (db 'nm '+Player "Jasper") returns nil.
<Regenaxer> Hi freemint, mtsd!
<mtsd> Im fine, thanks freemint! You?
<mtsd> Hi Regenaxer!
<freemint> I am a bit tired
<mtsd> Kids are home with sore throats and fever, but it has not reached me yet
<mtsd> Busy time at university, freemint?
<freemint> but (scan (tree 'nm '+Player)) has a "Jasper" entry
<freemint> mtsd yes but i did PicoLisp till 4 in the morning
<mtsd> haha, ok. That explains the tiredness today :)
<freemint> I fail to get my objects out of the database
<freemint> which is frustrating since the indexing is there
<Regenaxer> Hmm, why the 1 in (rel nm (+Sn +Idx +String) 1) ?
<Regenaxer> Default is 3
<Regenaxer> Not sure what it does then
<Regenaxer> Should be ok, it indexes down to single chars
<Regenaxer> Just a little waste perhaps
<freemint> I reduces the minimal length of indexed substring to 1
<Regenaxer> yes, so ok
<Regenaxer> Not sure why 'db' doesnt find it
<Regenaxer> (db 'nm '+Player "Jasper") is correct
<freemint> https://pastebin.com/f98smdnX here more details
<freemint> Ahh it does n't find substrings
<freemint> (db 'nm '+Player "Mad. Jasper") works
<Regenaxer> the entry "Joker" does not exist
<Regenaxer> only *inside* a name, right?
<freemint> yes
<Regenaxer> 'db' only finds full matches
<freemint> ahh, what finds non full matches than?
<Regenaxer> 'db' means "find the player with the name "xxx""
<Regenaxer> fg
<Regenaxer> *not* find the player whose name *contains* "xxx"
<freemint> ok, what function would do that?
<Regenaxer> So your code looks fine
<Regenaxer> pilog 'select'
<Regenaxer> pilog 'db' is like 'collect' which both also find full matches
<freemint> So i need to learn Pilog too?
<Regenaxer> (collect 'nm '+Player "Mad. Jasper")
<Regenaxer> (select +Player nm "Jasper") is also fine (it is based on select/3)
<freemint> Can you give me a simple example for pilog select?
<Regenaxer> (select (@Player) ((nm +Player "Jasper")))
<Regenaxer> (solve '((select (@Player) ((nm +Player "Jasper")))))
<Regenaxer> Not tested
<freemint> (T)
<Regenaxer> You find better examples for select/3 in app/gui.l
<Regenaxer> did you read the article about select?
<Regenaxer> in doc/select.html
<freemint> i read that for now
<Regenaxer> Thats best, select is not so easy to explain with a few sentences
<freemint> another problem my '+Joint with +built does not work
<freemint> (put> (db 'nm '+Player "Mad. Jasper") 'built (db 'nm '+Room "Diner" ))
<freemint> But there is no change to the Diner
<freemint> wait now there is
<freemint> Q
<beneroth> Good morning
<beneroth> you were discussing a lot :)
<freemint> Good Morning
<beneroth> freemint, +Joint is something which is not possible in SQL databases
<freemint> a joint breaks when insert a NIL
<beneroth> inserting NIL = deleting
<Regenaxer> Ho beneroth!
<freemint> it breaks it permanetly
<mtsd> Hello beneroth!
<beneroth> Regenaxer, ho ho ho :)
<beneroth> Hello mtsd !
<Regenaxer> :)
<beneroth> I hope your kids get soon better, mtsd :)
<mtsd> Thanks beneroth. It will be better soon, this time of year is always like this
<beneroth> Regenaxer, you can't really say that SQL has no garbage collection. yes, you need to actively delete stuff, not like in pilDB where objects without indexes fall out of scope automatically when they're not referenced anymore.
<beneroth> internally SQL dbs do a lot of garbage colllecting all the time
<Regenaxer> yes, but not on the application level
<Regenaxer> it cant detect that an object is no longer referred to, right?
<beneroth> no, but then there are no graph-like connections. everything has an index.
<beneroth> objects cannot reference each other
<Regenaxer> right
<beneroth> you can only hold a a key value which is a key in an index (foreign key)
<Regenaxer> you have indexes joining them
<Regenaxer> and if such an index is cleared, nothing becomes garbage
<beneroth> that is the fundamental difference between relational and graph - direct links between records, or everything goes via primary indices
<Regenaxer> right
<Regenaxer> so there is no garbage collection on the app level possible
<beneroth> no, but it is also not needed.
<Regenaxer> right
<Regenaxer> well, it is needed
<beneroth> well you have +Dep, as cascading delete
<Regenaxer> this is an add on
<Regenaxer> But pil has a db-gc on the object level
<beneroth> in SQL there is no object level :)
<Regenaxer> +Dep is knowledge of the app domain
<Regenaxer> right
<Regenaxer> freemint, +Swap is a bit tricky
<Regenaxer> It may behave unexpectedly
<Regenaxer> putting NIL may indeed delete the whole swap object
<beneroth> well if we have Head and Body-Lines (e.g. purchase order or whatever..well just a main and n related entries... very common in accountinge/erp applications, you know)... you can declare +Dep on the head entries, so when a head entries gets deleted, all body entries get also deleted automatically
<Regenaxer> In the GUI +Swap/R takes care
<Regenaxer> I think I never used +Swap with +Joint
<Regenaxer> may not work, as +Joint does not know about it
<beneroth> +Swap is mainly intended for big +String I believe?
<Regenaxer> +Joint makes sense for short lists
<Regenaxer> beneroth, right
<Regenaxer> or any other scalar data
<Regenaxer> +Joint for large amounts is actually (+Ref +Link)
<Regenaxer> +Joint and (+Ref +Link) are conceptualey equivalent
<Regenaxer> ie traversable in both directions
<Regenaxer> Just +Joint is a lot more efficient for relatively short lists
<Regenaxer> while (+Ref +Link) has no limits
<beneroth> freemint, whenever you work with some of the fields (properties) of a single record (object), the whole record has to be read from disk into memory (same is true for pilDB as for SQL databases). so if you have some big fields which are not so often used, it makes sense to put them into +Swap (or put it in another table with 1-1 relation) to prevent loading of the big field everytime you do something with the record.
<Regenaxer> Exactly
<mtsd> Regenaxer, about +Joint vs. (+Ref +Link). What would a limit be? I.e. when to stop using +Joint and go to (+Ref +Link)?
<freemint> beneroth, is there a problem with my scheme in that regard?
<mtsd> Approximately
<beneroth> Regenaxer, very early as a noob I over-used +Joint, which consequently resulted in bad performance. then I avoided it for a while, but now I use it more and more. +Joint is so powerful. you just have to think about how the referenced values are used.. most times when the main object is used? than use +Joint.
<beneroth> freemint, I haven't looked into it, sorry. I just wanted to explain you the motivation of +Swap, its basically the same as 1-1 relationships in SQL. In SQL teaching they might tell you should never have 1-1 relations, which is kinda true for the general case and for nice theory, but its not true in practice.
<Regenaxer> mtsd, I would say up to a higher 2-digit range is ok
<mtsd> Ok, thanks!
<beneroth> I agree
<Regenaxer> So freemint, I would not use (rel built (+Swap +List +Joint) contt (+Content))
<freemint> Why?
<beneroth> hm. I can imagine scenarios where this is meaningful.
<beneroth> apparently we're unsure that +Joint can handle +Swap :)
<Regenaxer> freemint, I explained above
<Regenaxer> yes, I does probably not handle it, and it is very inefficient
<Regenaxer> if the list is short, no +Swap is needed and all is ok
<beneroth> (rel built (+List +Ref +Link) NIL (+Content))
<Regenaxer> else use (+Ref +Link) instead
<beneroth> the order for the prefix-classes matter.
<Regenaxer> T
<beneroth> +List +Ref +Link is a list of indexed links.
<freemint> beneroth, indexed by what?
<Regenaxer> I think without +List
<beneroth> e.g. (+Ref +List +Link) is an indexed list of links (the whole list ends up in the index, not meaningful)
<Regenaxer> one content refers to N players
<Regenaxer> so a plain (+Ref +Link)
<beneroth> freemint, an index is basically just a list where (<index-key> object) ist stored. and index-key can be kinda whatever you like.
<freemint> beneroth, thx
<beneroth> Regenaxer, right, absolutely.
<Regenaxer> and contt in '+Content' disappears
<freemint> Regenaxer, i tried to include a Hook in my design
<beneroth> you can add a method to it for that.. e.g. (class +Content) (dm contt> () (collect> '+IdontKnowYourClass 'built This))
<beneroth> referring to the +Ref +Link instead of +Joint, not about Hook
<freemint> +Player builts N +Content. +Content is builtby 1 Player.
<freemint> A player might build much. And it might be interesting to be able to index each things a single player build efficiently
<freemint> Why is +Joint is a list and +Ref +Link is a B-tree with no indexing?
<freemint> *Why is-> IS
<beneroth> well then (class +Content) (rel player (+Ref +Link) NIL (+Player)) is the right thing
<beneroth> B-tree = index
<freemint> under a index i understand a function with maps elements of the key space to the valua space
<Regenaxer> yep
<freemint> what is the key space with +Ref +Link
<Regenaxer> so you have N player keys with the same content value
<beneroth> in databases, and index is a list of (key . record) pairs. this list is implemented usually as a b-tree for performance (to faster get to the right key entry, binary search).
<beneroth> Regenaxer, no, N content with the same player (author?) value, no?
<freemint> i did not get that
<beneroth> player 1 - N content. 1-n relationship (or 1-*, I don't know what notation you might have learned in SQL classes, freemint)
<freemint> yes
<beneroth> so every content belongs to one player. but many contents may belong to the same player
<beneroth> (class +Content) (rel player (+Ref +Link) NIL (+Player))
<freemint> yes that is not my problem
<freemint> index: Keyspace -> Value space
<freemint> (+Ref +Link): ??? -> ???
<beneroth> Keyspace = the list of keys. so here: list of all players who have at least 1 content
<Regenaxer> Hmm, in freemint's original version +Player had a (+List +Joint)
<Regenaxer> so N contents pointed to a single player
<beneroth> yes. 1-n relationship.
<Regenaxer> T
<Regenaxer> thus +Player gets a (+Ref +Link)
<beneroth> valuespace = list of all +Content objects which have an player
<beneroth> Regenaxer, ?? no, +Player does not now about content. content knows about to which player it belongs.
<Regenaxer> ah, no, I'm wrong
<beneroth> T
<beneroth> :P
<Regenaxer> beneroth is right
<Regenaxer> +Content gets the refs
<Regenaxer> I'm multitasking here, could not concentrate :)
<freemint> No harm done, still as much confused as before :P
<Regenaxer> ok :)
<Regenaxer> So what is the confusing point?
<Regenaxer> If there were no +Joints, we could do all with ref links, right?
<Regenaxer> (as ref is non-unique)
<freemint> Not sure
<Regenaxer> a single +Joint would be a (+Key +Link)
<Regenaxer> just inefficient
<Regenaxer> The +Link goes in one direction, and back you get via the +Key
<freemint> If i want to get from the +Content to the +Player i want a (rel creator (+Ref +Link) NIL (+Player))?
<beneroth> yes
<freemint> in +Content?
<beneroth> yes
<beneroth> so +Content has a property creator :)
<beneroth> which returns the external symbol of the player, the player object
<beneroth> holds
<beneroth> s/returns/holds
<Regenaxer> no, you get from +Player to the +Content with (rel creator (+Ref +Link) NIL (+Player))
<freemint> ???
<beneroth> Regenaxer, that he just said
<beneroth> I think?
<Regenaxer> He said "If i want to get from the +Content to the +Player$
<beneroth> freemint, the players external symbol is the value in the property 'creator in the +Content object
<freemint> yes
<Regenaxer> From content to the player he gets with the link
<Regenaxer> I was talking about the index
<beneroth> let's move slow
<freemint> beneroth, thx
<Regenaxer> yeah, in any case we have both directions
<beneroth> freemint, NIL is the argument to +Ref (it is nearly always NIL, used for Hook)
<Regenaxer> so we can get both
<freemint> yes
<beneroth> freemint, (+Player) is the argument for the +Link, tells which class the link value might be
<beneroth> (for validation)
<freemint> yes
<beneroth> (so you cannot put another +Content external symbol into the 'creator property)
<freemint> yes
<beneroth> because of the +Ref, an index gets created: (<player> . <content-object>)
<beneroth> you can use that index to get all +Content which has a player: (collect> 'creator '+Content) (no filtering)
<beneroth> ah sorroy
<beneroth> s/collect>/collect of course
<beneroth> (collect 'creator '+Content)
<beneroth> or you can use it to get the content of a single player: (collect 'creator '+Content PlayerObject)
<Regenaxer> To be sure about the current model, we have this:
<Regenaxer> (class +Content +Entity)
<Regenaxer> (rel creator (+Ref +Link) NIL (+Player))
<Regenaxer> right?
<freemint> yep
<beneroth> so I understood, yep
<Regenaxer> ok
<Regenaxer> A content has a single creator. Makes sense
<beneroth> (db 'creator '+Content PlayerObject) makes no sense, as (db) always returns a single object, but the relationship is +Ref so multiple values may exist for the same key.
<Regenaxer> The +Ref lets you collect or find all contents a single player has ever created
<beneroth> (db) returns the first match it finds, right Regenaxer ?
<freemint> ok
<Regenaxer> yes, db
<Regenaxer> but (collect 'creator '+Content This)
<Regenaxer> gives all
<Regenaxer> if This is a +Player
<beneroth> so you could use (db 'creator '+Content PlayerObject) to see if there the player has any content at all (NIL or one), but the one which gets returned is kinda pseudo-random (probably the first content which got related to that player)
<Regenaxer> T
<beneroth> (collect 'creator '+Content This) = (collect 'creator '+Content PlayerObject)
<beneroth> got it freemint ?
<freemint> when called with '(with 'PlayerObject
<freemint> yes
<Regenaxer> yep, though without quote if 'PlayerObject' is a variable
<beneroth> once you have a bit data in your database, you should do (show '{1}). you will see a list of properties which have another external symbol as value. (show) such an external object too... then you get to the index structure
<beneroth> (with PlayerObject (collect 'creator '+Content This))
<beneroth> or (with '{234} ...) when we assume that '{234} is a +Player object :)
<freemint> Question: why is (rel built (+List +Ref +Link) NIL (+Content)) better than (rel built (+Swap +List +Joint))?
<beneroth> try to make a diagram drawing of the external symbols involved
<freemint> I did
<beneroth> +Swap does nothing more than causing that, instead of the value directly (e.g. the +List of +Joint), instead another new external symbols name is stored in the value of the 'built property, and that other external symbols as the real value as its symbol value
<freemint> ok
<beneroth> so about +Joint: whenever you (put> 'Obj 'built ...) then this (put>) will not only be executed on the current object, but also on that other object which is connected by the joint. Because that is what +Joint is all about: keep two properties in different objects always synchronized!
<Regenaxer> And (+List +Joint) is equivalent to (+Ref +Link)
<Regenaxer> not (+List +Ref +Link)!
<beneroth> it not only has to change the built property, but also the 'creator property in the connected +Content, right?
<freemint> Regenaxer, what?
<beneroth> Regenaxer, T
<beneroth> freemint, ignore Regenaxer :P
<beneroth> he is nitpicking things you haven't grokked yet and which is not an issue yet :P
<beneroth> ;-)
<Regenaxer> good
<beneroth> sorry Regenaxer
<Regenaxer> no problem
<freemint> on change, yes
<Regenaxer> Just for the records
<beneroth> freemint, so for the +Joint, whenever you do (put>) on a joint property, it has to find the connected object and call (put>) on its property too, right=
<beneroth> ?
<freemint> It has to step trough a element long list, yes
<beneroth> the issue is now, with +Swap and +Joint combined, it might be that it cannot correctly find the connected object, because it doesn't take care that the value is not its target object but a another external symbol (the +Swap) which holds the real object in its value
<freemint> N
<freemint> mhh hwo can we test that?
<beneroth> I haven't tested +Swap +Joint. Regenaxer probably neither. it might work, its possible Regenaxer built something into +Joint so it correctly handles +Swap but he just forgot :P
<Regenaxer> I think it will not work
<Regenaxer> +Swap needs another indirection
<beneroth> make a +Joint relation. make two object. change their joint property values. show the objects and their values. compare.
<Regenaxer> the value of that symbol
<beneroth> aye
<Regenaxer> +Joint does not handle that automatically
<beneroth> and +Swap +Joint is a pretty unusual idea (for experienced pilDB dev), so you probably haven't handled it
<Regenaxer> and should not
<Regenaxer> right
<beneroth> though I would say it would probably be meaningful to allow +Swap +Joint, agreed? :)
<beneroth> not a pressing issue, but I can imagine use cases where it might be meaningful... or not
<Regenaxer> not meaningful
<beneroth> I'm still pondering
<beneroth> you're right, usually +Ref should be used than. OR another object in between
<Regenaxer> +Swap is for large data
<beneroth> well large list of +Joint? :P
<Regenaxer> but large +joint lists are not good. Should be (+Ref +Link)s
<beneroth> it violates the thumb rule of +Joint is for relations which are maximal up to 2-digit, which you just told mtsd :)
<beneroth> T
<Regenaxer> yep
<beneroth> Regenaxer, in my newest project I use a (+List +Joint) .. (+Joint). very nice!
<Regenaxer> Never used it before?
<freemint> benerorth i also have a neet thing:
<Regenaxer> BTW, (+List +Joint) <-> (+List +Joint) works too
<freemint> (class +Room +Content) (rel neighb (+List +Joint) neighb (+Room))
<beneroth> freemint, as an advice: maybe you can understand DB better by staying away from +Joint in the beginning. +Ref is also the equivalent to "normal" databases. but don't forget to come back to +Join once you grokked normal DB relations :)
<freemint> ok
<beneroth> Regenaxer, not really. I underused +Joint for a while :)
<freemint> a n-m self-joint and it works
<Regenaxer> I would not de-recommend Joints for beginners. They are conceptually easier and more direct Lisp
beneroth has left #picolisp ["Verlassend"]
<Regenaxer> no function calls and tree searches involved
beneroth has joined #picolisp
<freemint> when to use (+Ref +Link) vs (+Link)?
<beneroth> when you want to do (collect)
<Regenaxer> (+Link) is when you don't search for it
<freemint> ok
<beneroth> Regenaxer, you are right on a fundamental level. I'm not so sure if you are right with people which already got confused by SQL teaching ;-)
<Regenaxer> true
<beneroth> +Joint is very outlandish for people used to restricted SQL :)
<freemint> really?
<beneroth> and you cannot assume SQL people to have an understanding of its implementation, I'm happy if I can explain them the meaning of +Swap (or 1-1 tables in SQL) :D
<Regenaxer> Depends whether one still has sql in mind. The pil DB is so different that this perxaps does not happen
<beneroth> freemint, +Joint is one of the features that pilDb has which SQL has not and cannot have.
<beneroth> Regenaxer, T
<beneroth> freemint, +Joint makes pilDB into a "graph database"
<Regenaxer> +Link too
<Regenaxer> +Joint is just two Links maintained automatically
<freemint> I am aware, but in sql you model such graphs all the time by saying where key1=key2
<beneroth> T, +Link is in SQL usually (like always) a +Number instead :)
<freemint> +Link is the weird one
<Regenaxer> yes
<freemint> with SQL you can alwys go in both directions
<beneroth> freemint, the other thing I really love about pilDB which SQL cannot do, is inheritance. as in pilDB Entities are classes, you can do inheritance (the DB supports it well).
<freemint> with +Link not
<beneroth> no, with SQL you cannot go in both direction
<beneroth> well you can achieve it, but you do by getting two big lists and then compare it
<beneroth> in picolisp, you go directly from one thing to the other
<freemint> yes thats how they do it and it is works in both direction
mtsd has quit [Quit: WeeChat 1.6]
<beneroth> you can do that in pilDB too
<freemint> yes but in sql there is no way to built a +Link
<beneroth> run two (collect) and then compare the stuff with each other until you find something matching. that is what SQL does in fact :)
<beneroth> aye
<beneroth> therefore pilDB is conceptually more powerful than SQL DBs :)
<beneroth> can you see it?
<beneroth> nice talking, freemint, Regenaxer thx :)
<beneroth> bbl
<freemint> I m not sure. but that is another discussion
<Regenaxer> cu :)
<Regenaxer> The nice thing with links is that you chain them
<freemint> like?
<Regenaxer> for db- and non-db objects
<freemint> ?
<Regenaxer> I find things like (: home obj bank fk typ)
<freemint> ahh
<Regenaxer> home is the current form
<Regenaxer> has object
<Regenaxer> eg a Person
<Regenaxer> which has a bank
<Regenaxer> fk is Fibukonto
<Regenaxer> and this has a type
<freemint> +Joint is self maintaining , what about (+Ref +Link)
<Regenaxer> also
<Regenaxer> if you set a value (the link), the index (+Ref) is maintained
<Regenaxer> So in (: home obj bank fk typ) it traverses two normal objects and then two db objects
<Regenaxer> transparently
<Regenaxer> and *very* fast
<freemint> so i always need to update from the object where 'rel is based?
<Regenaxer> no db lookup
<Regenaxer> it stores the link *in* the object whose class has the 'rel'
<freemint> yes
<Regenaxer> then the rel (a daemon object) fires
<Regenaxer> same for +Joint
<Regenaxer> A joint may trigger this firing also in the second object
<freemint> ok
<Regenaxer> eg if that on still links to another one
<Regenaxer> So that one may fire too (be cleared)
<Regenaxer> A single put> for a Joint starts a whole machinery
<Regenaxer> In SQL you have to updadte *lots* of tables for that
<beneroth> T
<beneroth> or add a lot of database triggers, which us very ugly :)
<beneroth> maintenance horror
<Regenaxer> I see, I never used triggers
<Regenaxer> maybe did not exist back then
<freemint> So if i want to change the creator of all objects by Player1 . I (mapcar '((X) (put> X 'creator Other_person)) (collect 'creator +Content This_Person))
<Regenaxer> yep
<freemint> mmaybe with a 'for instead but ...
<Regenaxer> right
<Regenaxer> a little shorter
<freemint> and less consing
<Regenaxer> or, if the collect is very big, use 'iter'
<Regenaxer> not to build a huge list in memory
<Regenaxer> Easier than 'iter' is 'pilog'
<freemint> even less consing
<Regenaxer> yep
<Regenaxer> 'iter' is a bit low-level
<Regenaxer> you need to build the right keys for it
<freemint> oww
<Regenaxer> So most general is (pilog ((db creator +Content @Person)) (put> @Person) ..
<Regenaxer> forgot quote
<beneroth> pilog also uses (iter) under the hood, right? (same as collect)
<Regenaxer> I think it uses 'init' and 'step'
<Regenaxer> to be re-entrable
<beneroth> ah, right. makes more sense!
<beneroth> yes you are right! I knew pilog uses step. I forgot.
<Regenaxer> :)
<Regenaxer> in fact it is db/3 which does the job
<Regenaxer> in this example
<Regenaxer> more general is select/3 in pilog
<Regenaxer> A non-db example:
<Regenaxer> : (pilog '((lst @X (a b c d))) (printsp @X))
<freemint> Regenaxer, is there a way to do k-to-m-to-n relationships without intermediate objects
<Regenaxer> How?
<Regenaxer> k -> m -> n
<Regenaxer> so m intermediate objects?
<Regenaxer> moment, interrupt
<freemint> example trainA drives from TownC to TownB
<freemint> But TrainB also drives from TownC to TownB
<freemint> But TrainB also drives from TownD to TownC
<Regenaxer> ret
<Regenaxer> ok
<Regenaxer> you can put all destinations directly
<Regenaxer> arbitrary graphs
<freemint> Regenaxer, that is no longer a graph . It is a weighted Graph or a Multigraph but not a normal graph
<freemint> maybe with +Aux +Ref +Link?
<Regenaxer> Why weighted? You put also the distances?
<freemint> no TrainB is the value along the edge
<freemint> can we do 3 way connections without intermediate objects?
<Regenaxer> I don't understand that this is a 3 way connection
<Regenaxer> You could have trains as objects
<Regenaxer> and each train has a (+List +Bag) of connections perhaps
<Regenaxer> What kind of intermediate object is needed?
<freemint> Do you agree that a train connection is a Start x Train x Destination
<Regenaxer> Is +Pos in app/er.l such an object?
<Regenaxer> No
<Regenaxer> a train has a list of (start dest) lists
<Regenaxer> ie a +List +Bag
<Regenaxer> +Bag has limitations though. iirc +Joints dont work
<freemint> In as app/er.l you a have a mutli-way connection but you solved it with the +Pos untermediate objct
<Regenaxer> and +Ref +Link should be unique within a list bag
<Regenaxer> I have similar erp's without such a +Pos object
<freemint> Let me draw what i mean
<Regenaxer> in such cases I also use (+List +Bag)
<Regenaxer> I put item, amount, price etc directly into the order
<Regenaxer> Think about what list bag does. I think it solves your question
<freemint> I ment Hypergraph not multigraph
<Regenaxer> No idea about these terms
<freemint> just for correctness
<Regenaxer> ok
<freemint> A hypergraph is a graph where edges are not between 2 Objects but between N Objects
<freemint> maybe i should give you my complete reasoning
<Regenaxer> no need
<freemint> A joint is equivalent to a JOIN between 2 to SQL tables with fitting keys
<Regenaxer> I'm sure you can express everything necessary
<Regenaxer> You can put all kinds of links and scalars into a +Bag
<Regenaxer> ei
<Regenaxer> eg
<Regenaxer> (rel io (+List +Bag) # Einnahmen/Ausgaben
<Regenaxer> ((+String)) # Einnahme/Ausgabe
<Regenaxer> ((+Number) 2) # +Ein/-Aus
<Regenaxer> ((+Date)) # Datum
<Regenaxer> ((+Link) (+Mitarb)) # Mitarbeiter
<Regenaxer> ((+Link) (+Person)) ) # Firma
<Regenaxer> Can be extended indefinitely
<Regenaxer> all kinds of objects
<freemint> SELECT * FROM Start, Dest WHERE Start.ConnectionID = Dest.ConnectionID;
<Regenaxer> Just, as I said, be careful with Joints here
<Regenaxer> Dont bother me with SQL
<Regenaxer> try to express it in pil, it is a lot simpler
<freemint> is the same as (class +Town +Entity) (rel start (+List +Joint) dest (+Town)) (rel dest (+List +Joint) start (+Town))
<freemint> both start and dest are equal partners in that 2 way realtionsship
<Regenaxer> It makes no sense for a town to have a start, right?
<Regenaxer> it is a route
<freemint> It makes sense for a town to be the start or destination
<Regenaxer> if you want to index start an end, use (+List +Ref +Bag)
<Regenaxer> with start and end in the bags
<Regenaxer> the whole bag is indexed
<freemint> a +Joint is the same a JOIN of two tables
<beneroth> no
<beneroth> the only thing they have in common is that they can be used to achieve something similar.
<freemint> ok they archive something similar
<beneroth> but implementation-wise and also conceptually they're completely different
<freemint> ok
<beneroth> afk
<freemint> yeah you could say that
<freemint> SELECT * FROM Start, Dest, Train WHERE Start.ConnectionID = Dest.ConnectionID and Dest.ConnectionID = Train.ConnectionID;
<freemint> Is an equal marriage between 2 Tables
<beneroth> you have 3 tables in your select here :P
<freemint> yes?
<beneroth> Start Dest Train
<freemint> yes
<beneroth> so it's obviously not <freemint> Is an equal marriage between 2 Tables
<freemint> *3
<freemint> typo
<beneroth> polygamy :P
<beneroth> so, really afk now
<Regenaxer> see you beneroth!
<freemint> afk
<Regenaxer> freemint, try to get a fresh mind
<Regenaxer> Forget about SQL here, it is a cludge
<freemint> i think that cludge has something valueable here
<Regenaxer> Not sure, but in pil you can express the relations between objects directly, so no sense to compare that
<Regenaxer> Just point everything to everything you need
<Regenaxer> objects pointing to objects
<freemint> SELECT * FROM Start, Dest, Train WHERE Start.Name="Dresden" AND Start.ConnectionID = Dest.ConnectionID and Dest.ConnectionID = Train.ConnectionID; Is the collection of all Trains leaving from Dresden to anywhere
<Regenaxer> sigf
<Regenaxer> sigh
<freemint> SELECT * FROM Start, Dest, Train WHERE Tarin.Number=512 AND Start.ConnectionID = Dest.ConnectionID and Dest.ConnectionID = Train.ConnectionID; Is the collection of all Trains leaving from Dresden to anywhere
<Regenaxer> (collect 'leave '+Train <city>)
<freemint> *IS all connections where Train is involved
<Regenaxer> So what?
<freemint> I do not know how i would represent such a relation with PicoLisp
<Regenaxer> Where is the problem?
<Regenaxer> you have trains, cities (and optionally connections) as objects
<freemint> ok
<Regenaxer> if you dont want separate connection objects,
<Regenaxer> then put the connections as list bags into the trains
<freemint> ok
<Regenaxer> with (+Ref +Links) to the cities
<Regenaxer> Perhaps this is a similar case?
<Regenaxer> (rel lst (+List +Bag) # Vorbelegungen
<Regenaxer> ((+Date)) # Gueltig-ab
<Regenaxer> ((+Ref +Link) NIL (+USt)) # VSt-Satz
<Regenaxer> ((+Ref +Link) NIL (+USt)) # USt-Satz
<Regenaxer> ((+Ref +Link) NIL (+Fk)) # Fibukonto Warenbestand
<Regenaxer> ((+Ref +Link) NIL (+Fk)) # Fibukonto Wareneinkauf
<Regenaxer> ((+Ref +Link) NIL (+Fk)) # Fibukonto Warenverkauf
<Regenaxer> ((+Ref +Link) NIL (+Fk)) # Fibukonto Wareneinkauf (EU)
<Regenaxer> ((+Ref +Link) NIL (+Fk)) ) # Fibukonto Warenverkauf (EU)
<freemint> Would you consider using a connection object ugly?
<Regenaxer> I think I would try such objects first
<Regenaxer> makes it a bit cleaner
<Regenaxer> and, most of all, easier to extend
<freemint> oh i thought they were a kludge for some reason
<Regenaxer> you add more infos to each connection, times, special cars etc
<Regenaxer> no, a bag is just simpler if all is fixed
<Regenaxer> it is more tedious to add another column
<Regenaxer> needs perhaps an update pass over all existing bags
<Regenaxer> a new property can always be added
<freemint> ok good
<Regenaxer> and access is easier, by (get Obj 'prop) instead of (cadddr L)
<Regenaxer> The above lst is an extreme example perhaps
<freemint> So i would have a +Joint between Town and connection and a +Joint between +Train and connection
<Regenaxer> yes, but a +Ref +Link is better
<Regenaxer> iirc joint may have problems to maintain the deeply nested structures
<Regenaxer> it *does*, but gets undeterministic if the same object exists already
<Regenaxer> I think I always avoided joints in list bags for that reasog
<freemint> mhh
<Regenaxer> And typically there are many cities and trains
<Regenaxer> so joints are not optimal anyway
<Regenaxer> Not sure though, you could try
<freemint> I think i need to write an minimal example for +Ref +Link
<Regenaxer> yes, but we had one above with the players and creator
<freemint> I try that one
<Regenaxer> app/er.l also has several
<Regenaxer> eg (rel sup (+Ref +Link) NIL (+CuSu)) # Supplier
<Regenaxer> in +Item
<Regenaxer> A supplier has *many* items
<Regenaxer> so a joint is not feasible
<freemint> Ever thought of doing a binary tree or B-Tree joint?
<Regenaxer> How?
<freemint> +List like Prefix classs?
<Regenaxer> Build a binary tree of entities?
<Regenaxer> ah
<Regenaxer> No, because it would again blow up objects size
<Regenaxer> and a *small* tree makes no sense
<Regenaxer> then a +List is more efficient
<Regenaxer> remember every object needs to be fetched in memory
<Regenaxer> So huge objects being fetched just to search them is bad
<Regenaxer> A separate b-tree is searched efficiently
<Regenaxer> The rule is: Keep each entity object as small as possible (but as needed)
<Regenaxer> for the same reason we have +Swap, to get large lists etc.out of the way
<freemint> the reason why i seem to dislike +Ref +Link is:
<Regenaxer> the swap object is fetched only if the data are needed, but not when tfe objects are just fetched to search in them
<freemint> You need log(m) to find it. where m is the total number of items of all suppliers
<Regenaxer> T
<Regenaxer> But a large list is O(N/2)
<freemint> I dislike that deeply for some reason
<freemint> yes
<Regenaxer> right
<Regenaxer> links and joints are cleaner
<Regenaxer> and easier to use directly in Lisp
<freemint> So i was asking whether there is something nice like +Joint but with log(N)
<Regenaxer> But there are practical limitations
<Regenaxer> ok, so you can indeed build a tree of objects
<Regenaxer> but then you end up with log(N)
<Regenaxer> a b-tree *is* a tree of symbols too
<freemint> Is your soltuion to log(N) Ref2 or Hook?
<Regenaxer> Ref2 is for a different purpose, it adds a *bigger* index
<Regenaxer> Hook is good if the situation fits
<Regenaxer> log(N) is good
<Regenaxer> O(N) is worse
rob_w has quit [Remote host closed the connection]
<Regenaxer> I see no "solution to log(N)"
<Regenaxer> we won't get O(1)
<Regenaxer> except with link
<freemint> i viewed it +Ref2 the other way around: It allows you to add a local Hook without breaking the bigger index
<Regenaxer> Remember that SQL *always* does a tree search (if not optimized internally)
<Regenaxer> yes, in any case two indexes
<Regenaxer> I did not do Ref2 or Hook for performance reasons
<freemint> have you thought about making a hash table in PilDB
<Regenaxer> no
<Regenaxer> a tree is perfect
<Regenaxer> hash also involves searches
<Regenaxer> collisions
<freemint> Yeah
<Regenaxer> Dont worry about performance
<Regenaxer> these are not bottlenecks
<Regenaxer> Ref2 and Hook are there to get unique indexes
<Regenaxer> for non-unique data
<Regenaxer> not for performance
<Regenaxer> I must go
<freemint> ok
<Regenaxer> bbl
razzy has quit [Ping timeout: 246 seconds]
<freemint> My idea: Make a hash table which has a linked list (so buckets are not garbarage collected) of 2^something buckets. buckets are just symbols which +SWAP a list in to another file. buckets are in a seperate file and have fixed size and are next to each other. You can hash your key to a number, compute "offset" of the appropiate external symbol and fetch that bucket
<freemint> *are just external symbol which +Swap
freemint has quit [Ping timeout: 268 seconds]
<beneroth> re
<beneroth> tztz
<beneroth> one should try to understand (fully grok) the easy parts before trying to improve the complex ones.
<beneroth> or like Jordan Peterson likes to say "some young students want to reform world economy but cannot keep their rooms clean"
<beneroth> Regenaxer, I make myself a Todo to create an picolisp equivalent of a typical SQL database using (+Key +Number) and (+Ref +Number) instead of +Joint and +Link to illustrate for SQL devs their silly ways :)
freemint has joined #picolisp
<beneroth> have a nice weekend guys
beneroth has quit [Quit: Verlassend]
xkapastel has quit [Quit: Connection closed for inactivity]
<freemint> My proof of concept worked but it is so unoptimized that it is not worth it yet
freemint has quit [Remote host closed the connection]
xkapastel has joined #picolisp
<Regenaxer> ret
mtsd has joined #picolisp
pointfree has quit [Excess Flood]
pointfree has joined #picolisp
mtsd has quit [Quit: Leaving]
tankf33der has quit [Quit: Connection closed for inactivity]
xkapastel has quit [Quit: Connection closed for inactivity]
mtsd has joined #picolisp
mtsd has quit [Quit: WeeChat 1.6]
mtsd has joined #picolisp
mtsd has quit [Quit: WeeChat 1.6]
ubLIX has joined #picolisp
xkapastel has joined #picolisp
orivej has quit [Ping timeout: 246 seconds]