Skip to Content.
Sympa Menu

texmacs-users - [TeXmacs] Re: Solved: Re: why is <with|> so beastly?

Subject: mailing-list for TeXmacs Users

List archive

[TeXmacs] Re: Solved: Re: why is <with|> so beastly?


Chronological Thread 
  • From: Sam Liddicott <address@hidden>
  • To: address@hidden
  • Subject: [TeXmacs] Re: Solved: Re: why is <with|> so beastly?
  • Date: Mon, 21 May 2012 17:37:39 +0100

I found some interesting things with regard to macro evaluation. One was that my converting an xmacro to a macro with a tuple I could cause the args to get evaluated early enough so that merge didn't choke. I can then convert back to an xargs again.

<assign|zip-|<macro|t|<quasi|<tuple|<unquote*|<quote-arg|t>>>>>>

<assign|zip|<xmacro|x|<quasi|<zip-|<unquote|<map-args|identity|tuple|x>>>>>>


Surprisingly, not only is the quasi-unquote required in the zip macro, if it is missing the map-args tree-label gets ripped out before it is evaluated - ripped out but the zip- macro!

<assign|zip-|<macro|t|<quasi|<tuple|<unquote*|<quote-arg|t>>>>>>

<assign|zip|<xmacro|x|<zip-|<map-args|identity|tuple|x>>>>

<zip|a|b|c> returns <tuple|identity|tuple|x>

instead of <tuple|a|b|c>

now THAT was unexpected!

I'm sure I am supposed to be using eval-args here, but I haven't worked out how to safely call eval-args with unquote* and yet not using quote-arg, because using unquote* without using quote-args causes segfaults.


Sam


On Mon, May 21, 2012 at 9:53 AM, Sam Liddicott <address@hidden> wrote:
<concat|> is also beastly as it happens by accident. I can't replace <with|> with <assign|> because it produces a concat.
I've tried using merge as a hack to avoid producing a concat, but it seems that the <assign|> block must make it to the top-level in a concat or it is not executed.

<assign|nothing|<xmacro|x|>>

<merge|<assign|a|2>|<plus|<value|a>|2>> is a bad merge (but the second item is 4)

<merge|<nothing|<inactive|<assign|a|2>>>|<plus|<value|a>|2>> produces a good merge but the result is 2

I would convert my xmacro <args|1|...> to a tuple and pass it to another macro which will iterate over the items and insert the joiner and convert that to a merge... only that would require a counter variable and a <with> so I will try a tail-recursive method based on the commas example on the style sheet language reference.

So I tried this:
<assign|joinz|<macro|n|j|x|<if|<less|<arg|n>|<length|<arg|x>>>|<merge|<if|<greater|<arg|n>|1>|<arg|j>>|<arg|x|<arg|n>>|<joinz|<plus|<arg|n>|1>|<arg|j>|<arg|x>>>>>>

<assign|joinz|<macro|n|j|x|<if|<less|<arg|n>|<length|<arg|x>>>|<if|<greater|<arg|n>|1>|<merge|<arg|j>|<arg|x|<arg|n>>|<joinz|<plus|<arg|n>|1>|<arg|j>|<arg|x>>>|<merge|<arg|x|<arg|n>>|<joinz|<plus|<arg|n>|1>|<arg|j>|<arg|x>>>>>>>

<assign|join-args|<xmacro|x|<joinz|0|<arg|x|0>|<map-args|identity|tuple|x|1>>>>

with nothing but bad-merge 

So I decide to prefix each tuple member with the joiner and then just drop the first member of the new tuple, however that has the original problem of being able to pass the joiner character or being stuck with a concat tag. So maybe I can get rid of the concat tag using unquote*

....

anyway, it seems that concat is not at fault here, and is safe; so I settle with this macro set for joining; a tail-recursive joinz that takes a tuple, and a join-args which constructs the tuple

<assign|joinz|<macro|n|j|x|<if|<less|<arg|n>|<length|<arg|x>>>|<if|<greater|<arg|n>|0>|<arg|j>><look-up|<arg|x>|<arg|n>><joinz|<plus|<arg|n>|1>|<arg|j>|<arg|x>>>>>

<assign|join-args|<xmacro|x|<joinz|0|<arg|x|0>|<map-args|identity|tuple|x|1>>>>

Sam

On Mon, May 21, 2012 at 8:18 AM, Sam Liddicott <address@hidden> wrote:
What can I do to a <with|> block to evaluate it immediately?

Here is a perfectly sound LOOKING macro:

<assign|join-args|<xmacro|x|<with|join|<macro|i|n|<if|<equal|<arg|n>|1>|<arg|i>|<merge|<value|joiner>|<arg|i>>>>|joiner|<arg|x|0>|<map-args|join|merge|x|1>>>>

the first argument is used to join all remaining arguments, unless there is only one, in which case it is returned. Somewhat like perl's join, except that the join is done using "merge" so the the result can be used as an identifier.

However the result returned is a <with|> tag, which cannot be subject to further merging:

although <join-args|-|b-c> renders as b-c
<merge|a|<join-args|-|b|c>> gives: <error|bad merge>
and <get-label|<join-args|-|b-c>> gives: with

So I try messing about with some quasi unquote tricks:

<assign|join-args|<xmacro|x|<quasi|<unquote|<with|join|<macro|i|n|<merge|<value|joiner>|<arg|i>>>|joiner|<arg|x|0>|<map-args|join|merge|x|1>>>>>>

to see if I can get rid of the <with|> by evaluating earlier, but it doesn't work.

<quasiquote|<merge|a|<unquote|<join-args|-|b|c>>>>
and
<quasi|<merge|a|<unquote|<join-args|-|b|c>>>>

both give: <error|bad merge>

This is not the first time that <with|> has given me trouble by hanging around too long. At times, for hacks, I've used <assign|> to a global var and been glad the macro has not been re-entrant or recursive.

In other cases for a work-around I have resorted to functional programming tricks and use of <compound|> to construct the name of the macro to call, but here I really need <with|> in order to pass the join-character to the map-args macro, and because the map-args macro must be a macro name and not a literal macro - otherwise I would have tried quasiquote to construct that macro.

So what can I do to a <with|> block to evaluate it immediately?

Sam





Archive powered by MHonArc 2.6.19.

Top of Page