What can and can I not put into an expression

macros
metaprogramming

#1

TL DR:
Why does this work:
ex = :(X --> Y)
but not this:
ex = :(X <--> Y)

Longer description:
I work with biochemical reaction systems and I want to create a macro into which I can type the reactions and which the generates the differential equations for me, to be solved using DifferentialEquations.jl.

DifferentialEquations.jl already have a macro for this:

rs = @reaction_network begin
  2.0, X --> Y
  1.0, Y --> X
end

However since most of my reactions go in both directions I would want do be able to do something like:

rs = @reaction_network begin
  (1.0,2.0), X <--> Y
end

this would make a lot of things half as long. In addition I would like to have functionality to put in more things as reaction rates (pre declared constants, or function of the reactant concentrations. This way I could allow to have reactions with rates not necessarily linear to the reactants concentration).

Since DifferentialEquations.jl have a very similar function I decided it would probably be a task suited for a macro and have been reading up on them. However it seems like I cannot create expressions using <---> (to denote a two way reactions), and I have been unable to understand what’s the difference between

    ex = :(X --> Y)
    ex = :(X <--> Y)

Neither expression is valid Julia code to begin with, but what trait of the one way arrow makes it allowed, as opposite to the two way arrow?

cheers


#2

It depends on whether Julia can parse it, and indeed the way to find out is to try to make an expression. There are a bunch of unicode operatores, which probably include all sorts of arrows, maybe that could be for you?

Edit: haha, you beat me to it… Also please quote your code, see PSA: how to quote code with backticks


#3

Here’s the list of unicode arrows you can use as binary operators ;). Maybe one of them will fit your use case:


#4

Thank you, this works very well. Just one small thing:
First I tried and it worked very well

ex = :(X ↔ Y)

However then I discovered that their also was the arrows which are more common in chemical reactions, so I figured I might use them. However when I write:

ex = :(X ⇄ Y)

I get the error
"syntax: missing comma or ) in argument list"

On closer inspection I get that very same error whenever I use one of the errors subsequent to the arrow in the list you gave
(That is the arrows ⇜ ⇝ ↜ ↝ ↩ ↪ ↫ ↬ ↼ ↽ ⇀ ⇁ ⇄ ⇆ ⇇ ⇉ ⇋ ⇌ ⇚ ⇛ ⇠ ⇢ generates errors, but all others works fine). Now it will not be a major problem to use instead of , however I am curious of what this issue is about?
cheers


#5

There were some new arrows added recently, so these will be available at the next Julia version. ⇄ is an example of that.


#6

That is very helpful. Thanks


#7

Or we could use something like this to find usable operators with precedence:

julia> operators = sort([(Base.operator_precedence(Symbol(j)),i,j) 
           for (i,j) in 
               Base.REPLCompletions.latex_symbols if Base.isoperator(Symbol(j))]);

julia> [i for i in operators if contains(i[2], r"(?i)(?=.*left)(?=.*right)(?=.*arrow)")]
13-element Array{Tuple{Int64,String,String},1}:
 (6, "\\Leftrightarrow", "⇔")        
 (6, "\\Longleftrightarrow", "⟺")    
 (6, "\\leftrightarrow", "↔")        
 (6, "\\leftrightarrowcircle", "⥈")  
 (6, "\\leftrightarrows", "⇆")       
 (6, "\\leftrightarrowtriangle", "⇿")
 (6, "\\longleftrightarrow", "⟷")    
 (6, "\\nLeftrightarrow", "⇎")       
 (6, "\\nVleftrightarrow", "⇼")      
 (6, "\\nleftrightarrow", "↮")       
 (6, "\\nvLeftrightarrow", "⤄")      
 (6, "\\nvleftrightarrow", "⇹")      
 (6, "\\rightleftarrows", "⇄")  

Edit:
In case somebody don’t know we could use \rightlegarrows<press tab> to insert Unicode symbol into repl (or good editor)…