texmacs-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Texmacs-dev] Attempt to migrate to Guile 2.0 (need help)


From: Karl Hegbloom
Subject: Re: [Texmacs-dev] Attempt to migrate to Guile 2.0 (need help)
Date: Fri, 17 Jun 2016 16:02:46 +0000

PS:

In the Wizard Book, IIRC, (Structure and Interpretation of Computer Programs, MIT Press, G. Sussman and P. Abelson) there's an example where they start out with a single point of entry with a cond block that has to be extended for each new case, and then evolve it to a hashtable lookup instead, where you can register new functions without needing to edit the cond block in each "generic" function.

If I understand properly, each tm-define puts a new set of predicates into a sequence of them, and each sequence is tested until the one returns #t thus selecting the version of the tm-define'd function to run. I realize that my present understanding of how it works now is naive and incomplete, partly because I had not thought of these questions yet, prior to first or second reading of the source code...

Can the kind of contexts like this be sort of look-up environments, making a faster route to finding the right one happen? Is that what the logical resolution code is doing in there?

But then there's the temporally dependent...? before, during expansion, after; inside of partially evaluated, returning part of the evaluation or expansion of macros by being called as <ext|...> inside .ts,  and cursor vs non-cursor location dependent and source vs box tree dependent contexts... It's all a little confusing to me still.


On Fri, Jun 17, 2016, 09:39 Karl Hegbloom <address@hidden> wrote:

I think that perhaps the tm-module syntactic form ought to be left in place in all of the modules, as long as we need to continue to support Guile-1.8. But since it's no longer supported upstream itself, perhaps there's no reason why we need to continue to support Guile-1.8 in TeXmacs anyway. Perhaps we really ought to just port totally to Guile-2.n, (2.0 & 2.2), and drop out the support for older versions of Guile. In the process we should also drop or upgrade past any deprecated features, obviously.

What does the tm-module form give us over and above plain use-modules? It must expand to pretty much the same thing that use-modules does, perhaps even calling use-modules internally... or using it as a starting point. Since every TeXmacs module must have access to certain things, e.g., texmacs-glue, texmacs-user, etc. those can be implicitly and automatically in the :use form that tm-module expands internally.

I think the key to understanding enough about it to be qualified and capable of solving the problem, one must read the Guile sources after and during reading of the reference manual. I've compiled a deb of Guile-2.1.3 (effective version 2.2, development snapshot) and placed it available via https://github.com/KarlHegbloom/guile/releases along with a PDF of the guile-2.2 reference manual. You can use Github to browse the sources if you like, or just read them from the upstream repository, http://git.savannah.gnu.org/r/guile.git

Right now, I'm still very naive in my understanding of this system... I'm puzzling over things like whether it would be useful to use Goops or defgeneric for things similar to tm-define'd functions... but those aren't the same thing since they specialize based on predicates that run one after the next until one returns true, choosing the version of the tm-define'd function to run there. A generic function, by contrast, is specialized on the types of it's arguments. It's a different sort of overloading. So now I wonder if any of the internal mechanisms used by Goops or defgeneric can be utilized to improve performance of tm-define'd functions... The more I learn about it, the closer I get to being able to see the answer as obvious. At the moment, it's not.

I also wonder if tree->stree could usefully return a tree of goops objects, decending via some object heirarchy, perhaps built upon a customized metaobject protocol... Would that provide anything that the present way of things, using lists, does not? Could it potentially do away with the tree->stree and stree->tree thing, working directly with trees in some way? Can the internal C++ objects be mapped to Goops classes? Would that entail a performance hit, or would it be about the same? What are the trade-offs in terms of code readability, memory and processing-time performance, etc.? Would it make end-user client code more elegant? Would it get in the way, or facilitate programming?

I seem to recall seeing some sort of data structure that acts like a list, but which keeps a pointer to it's tail cell; maybe bidirectionally linked... but with Goops and generic methods, it could act just like an ordinary list, right? And could also hav eadditional behaviours, even decorated with mix-in's, and perhaps even sort of prototype-based like ECMAscript? Would that be useful? I keep thinking of the way that TeXmacs slows way down when the document tree structure is deep and complicated, so that it takes 5 or 10 seconds to catch up with my keystrokes when I type normal speed. I recently found a group of .tm manuals that I had not found before, since I don't think they are linked into the Help menu, and learned about the ip or inverse path, which points from the typeset tree back to the source tree. It explains that the algorithm is O(n^2). Well no wonder it takes it so long to catch up when I'm 4 levels deep in a nested outline! There has to be a way to either parallelize the search with multiple threads, or to maintain something along the way during expansion. I have not even a naive understanding of how it works now yet... There's a lot of code to read and my life and doodem obligations take up a significant amount of time also; but I won't quit. Without even looking first, and I'm not sure the problems are even resembling each other at all, but I recall seeing an algorithm for list set-union, set-difference or set-intersection or something that took the naive O(n^2) to O(n). Maybe it's in Emacs?

So Emacs Lisp and Guile Scheme have a number of important differences... one of them being lexical vs dynamic scope. In elisp you can wrap a function call with a let binding, and bind the value-slot (does the symbol-function behave the same way?) of a symbol that occurs free inside of the lexical scope of that function's definition. Each variable defvar'ed has a push-down list of values, and the top value is the one found at the time the function is called. So let pushes a new value on, and when the let scope is exited, a value is popped off. The example in the guile manual shows a scheme "equivalent" where they use let to capture the original value, set! it before calling the function, then set! it back after. But that's not the same, is it? What happens if multiple threads call that function, where one has set! the variable, and the other has not?

In TeXmacs, there are a number of scopes or contexts we must be aware of. There's the lexical scope around the definitions in the scheme code. Those are inside of module namespaces. Then there's the document source tree as well as the expanded or expanding typesetter box tree. There's paths into trees, independent of the cursor which belongs to... the editor, or the buffer? The view, right? My first naive attempt at getting the footnote number for the zotero-texmacs-integration failed since it always returned 0, since in the context it ran in, the typesetting environment had not been formed... I have to let the typesetter run by yielding to the main-loop after inserting a zcite that may expand into a footnote, and then call texmacs-expand to have the typesetter retrieve a reference binding for that footnote! But since the program can't predict the footnote number, it can not programatically form the reference label string, so I must have the macro, defined in tm-zotero.ts, insert a set-binding form with it's name containing the zcite ID as it's distinguishing uniquifying component, set to footnote-nr, which at the time the macro is expanded by the typesetter, contains the correct value.

This difference between relatively static source tree, dynamic typesetter box tree, the scheme environment, the typesetter environment, the path in the source, the path in the box tree, the cursor focus, the tree in general not considering the cursor... when and where and by what part of TeXmacs the code is called by, is sort of like the implicit 'this' variable passed to Perl objects or _javascript_ functions. Can that become part of what a special kind of generic methods uses for method dispatch? Of course this is what tm-modes are all about... the question is whether there's a way to exploit any method dispatch optimizations that the Goops provides, to improve performance or anything of tm-define'd functions?

I noticed that TeXmacs does not define any SMOBS. There is a clear separation between the Scheme side and the C++ side, and passing values from one to the other must go through a translation barrier. What is the cost of that?

What can be done to transform TeXmacs such that it becomes thread-safe? How does Guile's new garbage collection thread affect all of this?

These are things worth thinking over while walking and reading code and manuals from my Android tablet.


On Fri, Jun 17, 2016, 02:39 Massimiliano Gubinelli <address@hidden> wrote:
I’m also not very sure that changing texmacs-module with standard guile modules will work as expected. As far as I remember (but I can be wrong) texmacs-modules behave a bit differently than guile ones. One would have to inspect before their definition and see if this can be replaced by guile modules. maybe this is the reason your code fails.

best
max



On 16 Jun 2016, at 14:41, Darcy Shen <address@hidden> wrote:


I have migrated some existing statements that are not liked by Guile-2

item 1. conditional define
   (if (condition)      (define a ...)      (define a ...))    (define a (if (condition)      body1      body2))

item 2. curried define

   (define ((x a) b c)      (display a)      (display b)      (display c))    (define (x a)      (lambda (b c)        (display a)        (display b)        (display c)))

and use cond-expand for backward compatibility

Still don't know what's going wrong. I will try to extract the wrong pattern.

Since it works in init-texmacs.scm but does not work in a module, I guess that the problem is related to Guile's Module System.


---- On Thu, 16 Jun 2016 06:46:51 +0800 Massimiliano Gubinelli <address@hidden> wrote ----
Hi,

On 15 Jun 2016, at 17:07, Darcy Shen <address@hidden> wrote:

The problem is that after making tm-define.scm compile I can `tm-define` something in `init-texmacs.scm` and it compiles and works. But in the module `tm-preferences.scm`, it will cause a compile error where I use `tm-define`.


do you know what is going wrong? If I remember correctly my attempts to Guile-2 there were statements which were mixing compile-time and run-time evaluations (like for example conditional definitions) and they were not liked by Guile-2.

Max

_______________________________________________
Texmacs-dev mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/texmacs-dev


_______________________________________________
Texmacs-dev mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/texmacs-dev
_______________________________________________
Texmacs-dev mailing list
address@hidden
https://lists.gnu.org/mailman/listinfo/texmacs-dev

reply via email to

[Prev in Thread] Current Thread [Next in Thread]