What can and can I not put into an expression

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

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 https://discourse.julialang.org/t/psa-how-to-quote-code-with-backticks/7530~~

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

https://github.com/JuliaLang/julia/blob/26a2ea2c87e57ae0fcb57137efb1dc7d7bd888b1/src/julia-parser.scm#L17

2 Likes

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

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

2 Likes

That is very helpful. Thanks

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)…

1 Like