From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Stefan Israelsson Tampe Newsgroups: gmane.lisp.guile.devel Subject: The progress of hacking guile and prolog Date: Thu, 21 Oct 2010 22:23:23 +0200 Message-ID: <201010212223.23822.stefan.itampe@gmail.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1287692603 30841 80.91.229.12 (21 Oct 2010 20:23:23 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Thu, 21 Oct 2010 20:23:23 +0000 (UTC) To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Thu Oct 21 22:23:22 2010 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1P91fU-0001ma-M7 for guile-devel@m.gmane.org; Thu, 21 Oct 2010 22:23:21 +0200 Original-Received: from localhost ([127.0.0.1]:48763 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P91fT-0008Br-SO for guile-devel@m.gmane.org; Thu, 21 Oct 2010 16:23:19 -0400 Original-Received: from [140.186.70.92] (port=46969 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1P91fP-00089N-Nx for guile-devel@gnu.org; Thu, 21 Oct 2010 16:23:17 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1P91fK-0003TI-Ke for guile-devel@gnu.org; Thu, 21 Oct 2010 16:23:15 -0400 Original-Received: from mail-yx0-f169.google.com ([209.85.213.169]:42817) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1P91fK-0003T4-GS for guile-devel@gnu.org; Thu, 21 Oct 2010 16:23:10 -0400 Original-Received: by yxk8 with SMTP id 8so20038yxk.0 for ; Thu, 21 Oct 2010 13:23:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:subject:date :user-agent:mime-version:content-type:content-transfer-encoding :message-id; bh=ZQb6FH8Swi4xPh691Yk6ZtBRE27G+Ifm+KA+tWUofWY=; b=YrMYnKVyP99iveCPh46+HsV45ypIrVQ/6gB5YbcOL9JqauUHvPkbBeN6MzW/oFuHAV aRzIktjlzZRUEPRgxpoMGHZOS7cg3YC2oebtTFavewvx3+LoNT5U3KEUc3h6WSIFAIRn xSZhAa5DJ6r2+rVZsOt1ZM8NfbI8A2pS4zjCk= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:subject:date:user-agent:mime-version:content-type :content-transfer-encoding:message-id; b=cvSlVvJSQH8kgEhNw4zpEaL9OoCJlSdzysaBzkACsrCa2koH97wZxP92+S5g/XrMTQ YJoMUs4r/Du1ZYPh8rPj9g7qT+3z2gx9ih/OSvwpBOBsJQibu3Ni7P1X1KmlPDXpt0zU hGUgspM2b+2G06YuxfmDu3o/vkDoIMMv/weeg= Original-Received: by 10.103.121.10 with SMTP id y10mr2124286mum.72.1287692588580; Thu, 21 Oct 2010 13:23:08 -0700 (PDT) Original-Received: from linux-s4gz.localnet (1-1-1-39a.veo.vs.bostream.se [82.182.254.46]) by mx.google.com with ESMTPS id c25sm1073206fac.9.2010.10.21.13.23.05 (version=TLSv1/SSLv3 cipher=RC4-MD5); Thu, 21 Oct 2010 13:23:06 -0700 (PDT) User-Agent: KMail/1.13.5 (Linux/2.6.34.7-0.3-desktop; KDE/4.4.4; x86_64; ; ) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:11062 Archived-At: Hi, I think it's good to discuss what I do with the prolog and unifer. So this is what I've been doing. 1. Incorporate a theorem prover for extension and playing 2. Kanren like hygienic macro package 3. Make the c-code variables printable and hence much less segfaults at bt :-) e.g. robustify 4. Hygienify the fast umatcher. 5. try to design a type checker mimiking typed racket. 6. Play with compiled guile vm code to check for speed 7. Redesign and unugglify and improve the main prolog compiler 8. Introduce interesting features like higher order functional behavior. 9. Move the code over closer to guile Head. Hew oh well, thats feels like a lot, let's check it out. 1. The theorem prover (leanCop) is a nice exercise to incorporate and use because it uses quite a lot of prolog features and beeing able to compile that into working code led me back to read up about some of my ignorantic parts of prolog I've not setled here how to solve it. the thing is that one meld the operator parser in prolog to whatever one may like and use that to parse general code. I really don't like that the core languge changes behavior as you parse language x, and added a feature where the parser enters a new context e.g. the parsing language x and hence one can separate the two. This is not iso behavior although you can still modify the core language. There will be incompabilities but you can give the users some advice how to avoid these by using parenthesises. I think that this is a design choise for the better though. Anyhow with some luck there will be a code prover for guile in a couple of years :-) 2. Kanren is a nice way to program like with prolog, but using code more true to scheme. So I've been working with a hygienic macro package that should give such a feature. These macros will then be used in the prolog compiler to beutyfy it. I reallt think that this is the right way and really like what I've churn out so far. 3. The speedy umatch thingy was quite terrible to work with because it entered these home cooked c variables into guile which just segfaulted when trying to print it. (ugly) Anyway the print routine was hacked in my repo to print the it better. Still there probably are some dragons sleeping here but at least the coding experience is much better. 4. The umatch hackity hack was turned into a much more hygienic creature. Not perfect but at least it should now play much nicer with the macro system. The key issue was that everything was a defmacro (i did not now better then) and the matcher introduced syntactics from outer s(pace)cope so it was not to just bless the beast with (datum->syntax). One needed to take the x in (syntax->datum x) and split it up, tryying to keep bits of syntactic information to transfer it into the old macro compiler. Here comes a pretty cool hack actually. Consider the following module: ----------------------------------------------------------- (define-module (ice-9 syntax-matcher) #:use-module (ice-9 match-phd-lookup) #:export (match-syntax-hack)) (define (syntax-null? x ) (null? (syntax->datum1 x))) (define (syntax-equal? x y) (equal? (syntax->datum1 x) y)) (define (syntax-id x) (define (syntax? x) (not (eq? x (syntax->datum1 x)))) (if (pair? x) x (let ((r (syntax->datum1 x))) (if (pair? r) (let ((h (if (syntax? (car r)) (car r) (datum->syntax x (car r)))) (l (if (syntax? (cdr r)) (cdr r) (datum->syntax x (cdr r))))) (cons h l)) x)))) (make-phd-matcher match-syntax-hack ( (car cdr pair? syntax-null? syntax-equal? syntax-id) ())) ------------------------------------------------------------ syntax->datum1 transfer a syntax object to a datum for only it's root, e.g. it does not try to make everything a datum. id is a lookup creature and match-phd-lookup is a modded match generator that uses custom lookup or syntax-id as I call it. it's just an unpacking command that is done befor car cdr and pair? is executes like (let ((v (lookup v))) (if (pair? v) (f (car v) (cdr v)))) so it's a stupid efficiency hack so that we don't lookup all the time. Now syntax id will open up a pair and if some of them it's children is not of a syntax kind it will bless the child with the syntax of the parent syntax object. Now with this matcher I want to chop up the following structure (arg1 ... argn ((pat1, ..., patn code) ...)) and can then use: (define (my-unsyntax X) (define (unsyntax2 X) (define (unsyntax3 X) (define (unsyntax4 X) (match-syntax-hack X (('unquote X) (list 'unquote X)) (('uunquote X) (list 'uunquote X)) (('? X) (list '? X)) (('= X P) (list '= X (unsyntax4 P))) (('? X P ) (list '? X (unsyntax4 P))) ((H . L) (cons (unsyntax4 H) (unsyntax4 L))) ( H (syntax->datum1 H)))) (match-syntax-hack X ((Code) (cons Code '())) ((M . L) (cons (unsyntax4 M) (unsyntax3 L))))) (match-syntax-hack X ((X . L) (cons (unsyntax3 X) (unsyntax2 L))) (() '()))) (match-syntax-hack X ( (X) (cons (unsyntax2 X) '())) ( (X . L) (cons X (my-unsyntax L))))) It's not perfect syntaction but it is vastly better then before and the code is yum yum. 5) Typechecking is for safty and optimisation, in the end it can be cool to have and I'm working to understand all sides of this and have a pretty good idea what is needed. It will be a goos testcase for the code. 6) I copied the glil->assembly compiler and modded the code to spit out c-code in stead of assembly. For functions which does not call other scheme functions except in tail call manner this should be quite fast to adapt. And of cause loops becomes wickedly fast when compiling this way. Wingo:s example without consing tok 7ns for each loop on my machine. (For cleaned up C it should be less then 1 ns) Kind of interesting and a nice playground to try out optimisations directed by type inference. 7,8,9. No more to say but that you rock, upgrading to guile head was really a nice experience. Now I will continue to struggle with these topics for some time (I also hope to return to the postpone topic but to get the core in shape has higher priority) Happy Hacking : - ) /Stefan