IRC channel logs

2016-10-27.log

back to list of logs

<Common_Era>Hi.
<Common_Era> https://www.youtube.com/watch?v=iAl_MJCSJsM
<Common_Era>^ not me.
<Common_Era>My old neighbor made this and I want to die.
<kori>Common_Era: great album
<kori>although I think you might have pasted this in the wrong channel
<kori>Cheers
<Common_Era>No, this is where I meant it. Not an album, though.
<Common_Era>I'm sharing this everyone.
<kori>common era
<Common_Era>Oh. Who's it by? Never heard of it.
<kori>Belong
<kori> https://www.youtube.com/watch?v=sgilRyTintM
<davexunit>sneek: later tell civodul yeah, if the URLs aren't complete then that's a silly oversight on my part. I'd say "file a bug" but I don't have my shit together and there is no bug tracker.
<sneek>Got it.
<nalaginrut>morning guilers
<nalaginrut>I forked nash, and try to fix segfault with udstream rebasing, I'll send PR to the author when it's workable
<nalaginrut> https://github.com/NalaGinrut/guile-tjit
<void-pointer>I have a module/library problem
<void-pointer>I recently switched to using R6RS style exception
<void-pointer>And so the module/library tries to import raise
<void-pointer>But, the very different raise that is in the default guile environment is conflicting with it
<void-pointer>I am using the Guile style module/library declaration
<void-pointer>Is there anyway to keep all symbols from the default guile environment out so then I can just import the symbols I need from the appropriate modules (e.g. rnrs base and rnrs exceptions)
<void-pointer>Or do I have to switch to R6RS style library/module declarations?
<lloda`>void-pointer: this came up in guile-user recently, (define-module) has #:pure, it's documented. If you mean in the REPL, I don't know
***lloda` is now known as lloda
<void-pointer>lloda`: I was a bit confused about what the #:pure option did previously. What you said clarified it. This is going to save a lot of trouble with namespace prefixes and what not
<void-pointer>Hmm, only difficulty is making #:pure work. It doesn't list a "value" in the documentation and putting it in with nothing is definitely not working
<void-pointer>Nor does passing #t
<lloda>it doesn't take any parameters, you're supposed to just say (define-module ... #:pure). How does it not work?
<void-pointer>Got it to work. Turns out it was a different error that was making me think that was the issue
<berndj>does scm_dynwind_free make any guarantees about behaviour with a NULL parameter?
<civodul>ACTION rediscovers biwascheme via amz3`s https://github.com/amirouche/scheme-todomvc/
<amz3`>^^
<amz3`>btw this is not "perfect", I could improve on the design and refactor so part but basically it gives the idea behind recent work in the frontend side using javascript
<amz3`>the most interesting issue remains "isomorphic" application which are supposed to use the same code server side and client side...
<amz3`>erm, I've written it's inspired from elm, but basically it's the same principle used in reactjs with some oop-fu
<amz3`>there is also the issue of fractal component architecture which basically aims at making widgets composable
***karswell` is now known as karswell
<lluis>hi! is there any way to overload the operation '+' for a goops object I have defined? a regular 'define-method' raises a warning about overriding the core binding '+', and then fails finding a method for the internal number addition I use
<paroneayea>davexunit: wrote a little "functional setter" method for GOOPS
<paroneayea>that was easyl
<paroneayea>*easy
<davexunit>paroneayea: awesome
<davexunit>sauce?
<davexunit>paroneayea: I've been poking at an implementation of state machines as coroutines
<davexunit>which makes the state machine implicit!
<paroneayea> http://paste.lisp.org/display/329739
<paroneayea>davexunit: ^^^
<paroneayea>davexunit: whoa cool :)
<davexunit>paroneayea: neat!
<davexunit>for more memory efficiency I would remove the 'map' call so that you don't have to pay toooo much penalty for a functional setter
<paroneayea>davexunit: good idea
<davexunit>just cram everything into that for-each
<davexunit>but it's great that the code is so short
<davexunit>I wonder if it would also be more efficient to remove the branch in the for-each lambda
<davexunit>and simply copy everything and then overwrite the desired slot at the end
<davexunit>that's about all of the golf I can think to play on this code ;)
<paroneayea> http://paste.lisp.org/display/329739#1
<paroneayea>davexunit: hm, well it might be more efficient at least to put the eq? FIRST
<paroneayea>oops, first
<paroneayea>I'm guessing an eq? check is faster than slot-bound?
<davexunit>what does slot-bound? do?
<davexunit>can you not simply iterate over slots and blindly set them?
<paroneayea> http://paste.lisp.org/display/329739#2
<paroneayea>davexunit: nope, you can't
<paroneayea>because if you try to slot-ref an unbound slot
<paroneayea>it throws an error
<paroneayea>in goops
<davexunit>but can you not safely assume that the slot is bound since 'self' is an instance of that class?
<davexunit>or may an instance not have any value bound to a slot?
<davexunit>you can see I don't know much about GOOPS
<paroneayea>davexunit: here's a way you can throw errors
<paroneayea>davexunit: https://dpaste.de/AXQ9/raw
<paroneayea>davexunit: so it's not the blind setting that's the problem
<paroneayea>it's the blind ref'ing!
<paroneayea>and if you're ref'ing an unbound slot so as to use its value in the set
<paroneayea>well you might throw an error
<paroneayea>make sense?
<davexunit>I guess I need to understand why an instance of a class may have an unbound slot
<davexunit>this would be impossible in a record type instance
<paroneayea> http://stackoverflow.com/questions/24348474/why-can-clos-slots-be-unbound
<paroneayea>davexunit: ^^ looks like someone asked, and someone answered, that very question!
<paroneayea>though...
<paroneayea>it looks like in CLOS unbound slots get set to nil
<paroneayea>which seems more sensible :)
<paroneayea>oh nope
<paroneayea>that's some code being provided :)
<davexunit>paroneayea: thanks, that clears things up
<davexunit>there's a slot-unbound hook in CLOS
<davexunit>that may be overridden
<paroneayea>yeah there you go
<paroneayea>cool
<paroneayea>I don't totally understand the MOP but I respect that it evolved somehow from a lot of experience with "what do we need to do to maximize live hacking"
<paroneayea>cool to see that sometimes there are indeed methods to the madness
<paroneayea>including slot-unbound methods :)
<davexunit>Ruby has method_missing which people abuse with reckless abandon
<davexunit>but slot-unbound seems much more controlled
<davexunit>it's for slots, not for arbitrary methods
<paroneayea>one nice thing about goops/clos is that methods *aren't* bound to objects
<davexunit>yes
<paroneayea>I've come to realize, most of the things I really hated about managing classes
<davexunit>that's the key feature for me
<paroneayea>was trying to get all those methods to combine right
<davexunit>yup
<paroneayea>and usually people use *inheritance*
<paroneayea>just to manage methods!
<davexunit>and how about when you want to add an operation that is missing from, say, the Array class?
<paroneayea>which is clearly madness
<paroneayea>right
<paroneayea>eventually people just keep appending to the class forever
<davexunit>do you "monkey patch" and make everyone made at you
<davexunit>or do you make a new MyArray class?
<paroneayea>breaking things out into generic methods is much better
<davexunit>yeah
<paroneayea>davexunit: in some ways this is something I don't like about some of the attempts I've done where I try to do things with *just* records
<davexunit>seeing a bit of GOOPS/CLOS made me see that OOP doesn't have to be garbage.
<paroneayea>I end up also putting a lot of method slots on objects also
<paroneayea>or, slots for thunks, etc
<davexunit>yeah I do that in my records, too.
<davexunit>I haven't broken out GOOPS yet for my Lisparuga rewrite, but I think it will eventually see some action.
<davexunit>thus far record types have been the better fit.
<davexunit>doing mostly low-level stuff right now
<paroneayea>it does feel like generic methods are a better way to do that... I mean, I know I don't like it when OOP classes grow just to keep adding functionality, so maybe I should learn that lesson when doing things more functionally as well
<paroneayea>cool davexunit !
<paroneayea>having fun with it?
<davexunit>having fun with GOOPS?
<paroneayea>davexunit: I meant with the rewrite
<davexunit>paroneayea: it's going okay. I hit a wall the other day that I think I got mostly over last night
<davexunit>regarding the state machine thing
<davexunit>basic multiplexing so that only one "state" is receiving keyboard input and such
<paroneayea>davexunit: cool, good luck with it... keep me posted :)
<davexunit>paroneayea: I will. no rendering at all yet.
<davexunit>but I did write a basic state machine that lets the user go through the intro screen, to the main menu, to the "game" itself.
<paroneayea>\\o/
<davexunit>so I think I have nearly all of my non-rendering building blocks.
<paroneayea>sweet
<davexunit>live coding potential still a bit unknown, though... we'll see.
<paroneayea>davexunit: btw, I was interested to find out that CLOS' predecessor introduced *both* inheritance and mixins (the latter of which I've come to think are probably a better route for adding structure to things)
<paroneayea>and was called "Flavors"
<paroneayea>because of an ice cream shop
<paroneayea>which is where the term "mixins" comes from!
<davexunit>wow
<davexunit>neat bit of history!
<paroneayea> https://en.wikipedia.org/wiki/Flavors_(programming_language)
<paroneayea>originally it used message sending, but then switched over to generic methods
<paroneayea>but yeah, fun
<paroneayea> https://en.wikipedia.org/wiki/Mixin#History
<paroneayea> https://upload.wikimedia.org/wikipedia/en/8/8c/Seafoodsundae1.jpg
<davexunit>hah and the ice cream shop was in Somerville
<davexunit>where I was living until recently
<paroneayea>compsci history is so much fun
<paroneayea>though I guess I'm veering into compsci factoids territory ;)
<paroneayea>also fun!
<davexunit>it's interesting how much of it happened in my home state
<paroneayea> http://www.theonion.com/article/un-factoid-finding-mission-discovers-liberia-about-677
<davexunit>thanks MIT
<davexunit>hahaha
<daviid>'belgian fudge' ... haha
<amz3``>what do you call generic methods in terms of GOOPS,
<amz3``>what do you call generic methods in terms of GOOPS?
<daviid>generic funtion, not generic methods
<amz3>yes
<amz3>what are they in terms of guile?
<daviid>amz3: a generic function is a 'container', a bit of reading would help you here
<daviid>paroneayea: nice! I beleive with a bit of reading of source code, in 2.2, they might be a more efficient way to write slot-fset, don't know, but cool work anyway
<daviid>paroneayea: i'd write ... (unless (eq? slot-n slot-name) (when (slot-bound? self slot-n) ...)) but matter of taste i guess
<paroneayea>daviid: yeah I dunno... I did base this off of code from 2.0.X
<daviid>for info, gauche also implements stklos, and iirc, in gauche, everything is an object
<paroneayea>daviid: would be happy to have more efficient versions going forward... happy in the meanwhile that it was pretty easy to get a first version of
<daviid>paroneayea: it's really nice you are using goops and inviting davexunit to do so too, when/where appropriate
<paroneayea>daviid: GOOPS is fun! and good live hackability + generic methods are strongly desirable :)
<daviid>paroneayea: it is my intention to study, and change goops, so that it does not divert from the clos protocol for the subset it implements
<paroneayea>maybe with an option that uses less mutation, there would be less grumpiness about GOOPS
<daviid>paroneayea: the important thing, and history helkps a lot, a generic function based oop is perfectly compatible with fp
<paroneayea>or rather, less mutation in its interface at least, even if it uses mutation to manage the method dispatch table, etc
<paroneayea>daviid: right
<davexunit>it would be nice to make classes that have getters but not setters
<davexunit>in Ruby I can do this by only exposing instance variables with attr_reader
<paroneayea>davexunit: you can already do that in GOOPS now sort of, by using #:getter in goops but not using #:setter / #:accessor
<paroneayea>however, you can always (slot-set!) if you want to
<davexunit>okay
<davexunit>that works well enough, I think
<davexunit>it's the same with records
<daviid>it has been invented exactly to this purpose (it took +- 30y of our best s/w engineers to come to it ...
<davexunit>you can always use the low-level setter for struct fields
<daviid>davexunit: as paroneayea said, just don't use solt-sert! and class redefinition on the fly
<davexunit>I'm not one of those "it must be *impossible* to mutate!" people
<daviid>slot-set!
<daviid>davexunit: i'm against that idea
<daviid>as if scheme defines set! so let's get rid of the language itrself, it's bad ...
<davexunit>it's a very Haskell-like pure-FP-by-divine-edict thing
<paroneayea>btw
<paroneayea> https://web.archive.org/web/20160311212643/http://mumble.net/~jar/articles/oo.html
<paroneayea>davexunit: daviid: ever read that ^^^?
<paroneayea>good discussion of "what does OOP mean?"
<paroneayea>and it turns out, "a whole swath of things"
<paroneayea>and often, some things and not others
<davexunit>paroneayea: I think I read this a couple years ago
<davexunit>it's good
<daviid>never force a programmer, he/she knows better then the language spec what and when to do (use set! or not ...) it always must remain an option to set, imo of course
<daviid>paroneayea: not that article, but i did read a lot of stupid things, written by 'young' generation not knowing anything about clos and gf based oop ...
<davexunit>ACTION tries to make a "___ in the streets, ___ in the sheets" joke about mutation at the top-level and functional in the middle
<daviid>it's like optical microscopy, humanity isa loosing that knowledge because nost youg people only train electronic microscopy ...
<davexunit>ACTION fails
<daviid>pure fp must be an option, not an obligation. in my work, they are things that would simply not work in pure fp
<paroneayea>> If CLOS and Dylan claim to be OO, then their definition of OO has to be Lisp's. But they obviously aren't OO in the Simula or Actors senses. This is exactly what you like about them. But the terminology confusion may contribute to the lack of acceptance of generic functions in mainstream languages. You are trying to invade linguistic territory (the space of the meaning of "OO") where you're not wanted. I can see why you'd want to do
<paroneayea> that, since OO has such cachet, but perhaps a different buzzword would be in order.
<paroneayea>FTA
<paroneayea>probably a good point that associating OO with say, Java in 2005, has lead to some other things on that list getting looked down upon that might be valuabe
<paroneayea>eg generic methods
<davexunit>yeah that's an interesting observation
<davexunit>generic methods were definitely an "a-ha" moment when I learned about them
<davexunit>tangentially, functional programming is strongly associated with Haskell
<davexunit>which leads many to assume that part of functional programming is static type systems
<daviid>paroneayea: yes, we need to teach to the world, again :), what is a generic function, polymorphic, multi-method oop system is, where it comes from, why it has been invented, and why it is an order of magnitude superior to any other oop system
<daviid>we need to teach yougs that gf is fp compatible, because appart from slot-ref slot-set!, the entire knowledge is in methods, not in classes
<daviid>be back...
<davexunit>yeah that's what I like about generic functions
<davexunit>generic functions can be used without using classes, too, which is also nice.
<davexunit>it's a useful concept on its own
<paroneayea>also an easy concept to implement :)
<davexunit>are they? I've never done it
<davexunit>paroneayea: you did for your activitypub implementation, right?
<paroneayea>yup
<paroneayea>pubstrate's main system can't use GOOPS for a specific reason (a single instance can be multiple types at once)
<paroneayea>so I implemented generic methods
<paroneayea>was < 50 lines I think
<davexunit>neat
<davexunit>I'd be curious to see that code
<davexunit>I'm not sure where I'd start if I wanted to implement it
<paroneayea> https://blog.wikimedia.org/2016/10/26/internet-archive-broken-links/
<paroneayea>davexunit: it's pretty easy... SICP has a section on generic methods too
<davexunit>really? and I thought that I knew the book well...
<davexunit>missed that!
<paroneayea>basically you have some table that the procedure dispatches on
<paroneayea>in SICP they combine it with message passing I think
<paroneayea>but here I just attached the hashtable to a procedure property
<paroneayea>so the procedure, when invoked, looks at the first argument's type, then finds the appropriate method to apply
<paroneayea>from its hash table
<davexunit>paroneayea: alternatively, you might be able to use a global weak key hash table
<paroneayea>davexunit: yeah they do something like that in SICP I think, attached to "packages"
<davexunit>ah okay
<paroneayea>but, I preferred to have the table just be attached to each method
<paroneayea>davexunit: let me see if I can find the section
<davexunit>the advantage of a global table would be that you can hide it away
<paroneayea>they do it a bit differntly than my route... mine "looks" a lot more like GOOPS
<paroneayea>I'm not sure how GOOPS does it though, if it uses a global table or procedure properties
<paroneayea>oh yup
<paroneayea>(set-procedure-property! generic 'name name)
<paroneayea>in goops
<davexunit>hah
<paroneayea>so I'm guessing GOOPS does the same thing
<davexunit>what file did you find that in?
<paroneayea>goops.scm
<davexunit>neat
<paroneayea>davexunit: if you use a global table you have to associate the symbol of the procedure with the table
<paroneayea>if you just attach it to a procedure property, then you can use keep it more modular
<paroneayea>as in, multiple modules can have the same procedure name doing different things
<paroneayea>I have a (define-generic) and (define-method) type thing
<davexunit>my idea with a global table would be purely to abstract it away so no one could see it
<paroneayea>so you call the first to set up the generic, which is a method that looks at its own property table
<paroneayea>and the second to add new methods to it
<paroneayea>davexunit: hm, you might also be able to "hide" it with good old fashioned closure
<davexunit>I'm not sure about that
<paroneayea>(define my-generic
<paroneayea> (let ((dispatch (make-hash-table)))
<paroneayea> (lambda args
<paroneayea> ...)))
<paroneayea>hm
<davexunit>how does one add to the table?
<paroneayea>right.
<paroneayea>that's true.
<paroneayea>that's probably why I used procedure properties
<davexunit>yeah
<davexunit>a procedure property seems to be the right way :)
<paroneayea>davexunit: oh well, if someone wants to modify the procedure property table, that's probably as much trouble as doing set-cdr!
<paroneayea>as in, you better know what you're doing :)
<davexunit>yup :)
<davexunit>it's fiiiine
<paroneayea> https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-18.html#%_sec_2.5
<paroneayea>davexunit: ^^^
<paroneayea>in the numeric tower section
<paroneayea>that's how you set up different types of procedures for adding/multiplying/etc on different types
<paroneayea>I think procedure properties, if you have them, are simpler though.
<davexunit>I'm goign to use generics to re-do my vector math interface
<davexunit>going*
<paroneayea>davexunit: cool :)
<davexunit>I support 2D/3D/4D vectors, and the vector arithmetic operators are polymorphic
<davexunit>generics will provide a nicer way to deal with it
<paroneayea>davexunit: btw, the generics system I wrote *does* have inheritance, because ActivityStreams has it
<paroneayea>but you don't *need* inheritance for generics
<paroneayea>in fact SICP has a whole footnote snarking on people who think you do :)
<davexunit>Sussman took great pride in those footnoes
<davexunit>footnotes*
<paroneayea> https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-18.html#footnote_Temp_289
<paroneayea>davexunit: when I met Sussman in his office he was like "be sure you read the footnotes! I put a lot of jokes in there!" and in fact pointed at this very footnote
<paroneayea>and had Jessica and I read it
<paroneayea>and he was grinning like "get it???"
<paroneayea>and I fake smiled because I had to go home and read it a couple of times to get the joke
<davexunit>paroneayea: I don't think I get the joke :)
<davexunit>I get that it's a dig at OOP
<davexunit>(Sussman also mentioned that to us at FSF30)
<paroneayea>I think, in retrospect, that the punchline is "you're going to need strong AI in order to be able to reason about inheritance"
<paroneayea>or at least, some powerful ai methods
<paroneayea>> In fact, we suspect that these problems cannot be adequately addressed in terms of computer-language design alone, without also drawing on work in knowledge representation and automated reasoning.
<davexunit>alright, now I get it :)
<paroneayea>:)
<void-pointer>Just spent a lot of work making my unit testing library package be R7RS and R6RS compatible in addition to working on Guile. Large refactor and a lot of work. Guile can run the Guile version and the R6RS version. Got Chicken running the R7RS version. Need another implementation to check the R6RS version.
<void-pointer>Now, the problem is, I have a whole lot of documentation to update
<void-pointer>Downside of writing so much documentation so early
<davexunit>writing docs: not even once
<paroneayea>haha
<paroneayea>rough void-pointer
<paroneayea>yeah it can be hard to know when to write docs
<paroneayea>but, writing them earlier and rewriting is probably better than writing them never :)
<void-pointer>Well, I had a decently working version that was Guile specific and wrote full docs for it. Decided to make more portable, which I wasn't planning on before, so got to update
<daviid>paroneayea: wrt to sussman comment, i have to say this: clos is a language, and like any other, it takes time and experience to understand and properly use it, like 10 years or a couple of thousands of lines of code, reviewed by others, experienced clos folks, there is no way out. proper design is terribly difficult, it just is, no way out either
<paroneayea>daviid: Sussman was talking about inheritance as a concept, not as specific implementation, though
<daviid>paroneayea: yes, my comment is general either
<daviid>either/also
<paroneayea>and i think was talking about the difficulty of walking and reaoning about an inheritance graph that you get with say, an "inheritance diamond"
<paroneayea>which is known to be hard
<paroneayea>though, I think inheritance diamonds are also much worse when you're attaching methods straight to objects, rather than using slots for data only
<paroneayea>because you're incentivized to do really complicated inheritance to add "new functionality"
<daviid>paroneayea: exactly, but, that does not, unlike it has stupidly being said somewhere else, radicaly reject clos, goops ande gf based system in general to be used
<paroneayea>daviid: right, I don't think that Sussman was radically rejecting CLOS... I'm not even sure CLOS existed at this point :)
<davexunit>I don't think it did
<paroneayea>daviid: Sussman gave a nice talk recently that was mostly about advocating for generic methods and the desirabilty of live hacking!
<daviid>paroneayea: yes (with all the above :), and cool to promote, where and when applicable of course, the use of gf
<paroneayea>I think one nice thing about generic methods over "attaching methods to objects" also:
<paroneayea>you probably only need generic methods for about 10% or so of the functions that apply to your objects, and it's really useful there, but at least you can use plain functions elsewhere
<paroneayea>whereas in languages like Python, once I start providing methods, I feel like all the functionality I should tack onto to the class
<paroneayea>even when I could put it in a separate function
<daviid>paroneayea: yes, the entire knowledge of the 'susyem' in methods ands procedures of course
<paroneayea>that doesn't need *any* dispatch
<paroneayea>it's just easy to get in that mindset
<paroneayea>daviid: susyem?
<paroneayea>(system?)
<daviid>davexunit: 2d, 3d, 4d vector, in theory yes, but fast math, avoid clos/goops, dispatch is dynamic, a high performance penalty a gamer can not pay, imo
<daviid>susem/system
<davexunit>daviid: it's very useful.
<paroneayea>I think wingo said in some talk that having a nice JIT might be able to reduce the costs of dynamic dispatch
<davexunit>I can do my own benchmarks, thank you.
<daviid>davexunit: yes i know, but 1 order of mag slower, by def
<paroneayea>daviid: though that might not be where the cost is, for some of this.
<davexunit>I already do polymorphic functions for vector math, just with pattern matching
<daviid>davexunit: but at compile time right?
<davexunit>no,
<paroneayea>pattern matching is often O(n) the number of patterns right?
<paroneayea>worst case
<davexunit>that information can't be known at compile-time
<daviid>davexunit: anyway, i'd be interested by some bench, if you have abnything to compare with
<davexunit>anyway, it has been a bottleneck in any trace I've done of my code
<davexunit>hasn't*
<davexunit>ugh, bad typo!
<daviid>:)
<davexunit>I can always provide specialized operators in situations where performance is a problem
<davexunit>and have DWIM convenience everywhere else
<daviid>davexunit: in that case, it could well be that goops would be faster, because a lot has been taken care in implementation to accelerate thisd botleneck dispatch
<davexunit>there's a lot of cases to be considered given that's actually 4 types
<davexunit>scalars, 2d vectors, 3d vectors, and 4d vectors
<stis>heya guilers!
<stis>paroneayea: You can index your matcher.
<stis>prolog uses that and you can get essentially o(1) in many cases
<wingo>guile has some suboptimalities in the way that it compiles `match'
<wingo>ends up re-checking many things many times
<stis>wingo: Do you know of a matcher for scheme that can add new matchers dynamically?
<stis>something like a function (set! new-match-obj (prepend-matcher pattern lambda match-obg))
<stis>and be used like (match match-obj obj)
<stis>prolog has these objects and they are quite neat when writing proof solvers
<wingo>i don't know of something dynamic
<wingo>only racket's which is syntactic
<stis>indexing is useful for these objects cause they can represent a match with hundred or even thousands of macth clauses
<stis>thx wingo: WOuld you like me to write such a matcher for guile?
<wingo>is indexing like will clinger's paper on compiling "case" ?
<stis>don't know, I used a standard AI reference book as a base of it.
<stis>you build up a datastructure representing all patterns
<stis>a (cons p1 p2) would be (list #:cons (mk p1) (mk p2))
<stis>each level has atom hashes and a list of all match-lines that are satisfied for the current context in case you are matching with a variable
<stis>also all variables in the patterns yields a field.
<stis>so something like
<stis>(#item car cdr atoms variables all)
<stis>where car is all the cars at ths level (assuming it is a cons) cdr similarly and atoms a hash of all the atoms and variables a list of all lines having a variable at this point etc
<stis>the atoms map values are a list of match lines whose pattern have the key atom at this place
<stis>actually bitvectors are a great match for maintaining the set of match lines
<wingo>sounds pretty neat :)
<stis>The indexer will result in a list (a,b,c,...) of matching match lines and they are then applied sequecntually
<stis>for each of these values the true pattern is matched because it is difficult to index precislety
<stis>you can always get a few lines that will not match.
<stis>The typical case is (match '(1 1) ((x x) ....)
<stis>here the indexer assumes (match '(1 1) ((x y) ...)
<stis>this means a duplicattion of evaluation, and small matchers is better served by normal sequential matchers
<stis>also (macth x ((a1 , ... , a100) code)) is a bit heavy to translate precisly so what one does is to cut the sequence and compile in e.g. the pattern (a1 a2 a3 ... a5) or such
<stis>also (macth x ((a1 , ... , a100) code)) is a bit heavy to translate precisly so what one does is to cut the sequence and compile in e.g. the pattern (a1 a2 a3 ... a5 . l) or such
<stis>vectors could be translated to lists, the same for simple structs
<stis>A set datastructure as a bitvector is especially good because it represent an ordered set whith is awsomely fast operatoins for union intersection and negation
<stis>which can be used when one apply and pattern and or patterns
<stis>It does not scale though. at Over 10000 match lines this overhead start to tax
<stis>In guile log I have an indexer in C that employs the algorithm illuminated discussed above
<stis>I made it so that it is functional and whenever it is used for the first time in indexes the datastructure
<stis>which means that it is kind of slow if one intermingles construction and execution.
<stis>The usage pattern is really optimized for a construction phase and a usage pphase
<stis>but it does backtrack really efficienlty if one keeps a phased approach
<stis>I build up these datastructures out of functional trees with the leaves vhashes
<stis>the vhashes are modified to backtrack e.g. if the state is not stored it will mutate back to it's original state
<stis>This because vhashes have bad characteristic when one backtracks
<stis>I can get a way with this because I keep a list of all backtracked matchers and when I store a state i cycle through this list and martk all vhashes
<wingo>ACTION going to have to study this some time
<wingo>cool stuff :)
<stis>:)
<stis>marked vhahses will backtrack like normal vhashes
<stis> https://gitlab.com/tampe/guile-imatch
<stis>This scales quite okej in many circumstances but we should trim the vhashes at times
<stis>probably does not even compile just for reading atm. But you can see how a dynamic matcher with an index is constructed and everything is functional
<stis>then you might want to add features like proper unification, macros more effective indexer, or patterns and perhaps even and patterns
<stis>now it's bed time CU