Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add more unary operators #18139

Open
cstjean opened this issue Aug 19, 2016 · 23 comments
Open

Add more unary operators #18139

cstjean opened this issue Aug 19, 2016 · 23 comments
Labels
parser Language parsing and surface syntax

Comments

@cstjean
Copy link
Contributor

cstjean commented Aug 19, 2016

Julia has an impressive list of binary operators, but the unary operators are quite lonely: (+ - ! ¬ ~ |<:| |>:| √ ∛ ∜), and most of them have existing meanings. Having a lot of operators makes it easier to define nice-looking DSLs. I can't think of too many mathematical unary operators, except maybe DAGGER † (can we have post-fix unary operators?) so perhaps we could grab ~random unicode characters (☼💣❖) and call them unary?

@StefanKarpinski
Copy link
Member

I'm confused by the thinking here. Why would we want to make some random set of characters into unary operators?

@JeffBezanson
Copy link
Member

There are a couple postfix unary operators, namely A' and A.'.

To add more, there needs to be an argument that a character has been used as an operator e.g. in some subfield, or that its only reasonable use would be as an operator, etc. It can't just be random characters.

@cstjean
Copy link
Contributor Author

cstjean commented Aug 19, 2016

The sunshine suggestion was fanciful, but there aren't a whole lot of clean unary operators in mathematical notation. Most of them are diacritics or some form of brackets, and neither of those are suitable for Julia. Could we at least get the Hermitian operators † and ⊹?

Perhaps that's a different problem, but the way MacroTools handles variables: @capture(ex, f_(args__) = body_) would also be cleaner if there was a unary operator to denote "This is a variable in a pattern matching algorithm"

@JeffBezanson
Copy link
Member

Could we at least get the Hermitian operators † and ⊹?

Those are both currently invalid characters in julia, so yes this definitely seems possible. has unicode category Sm, the same as most other mathematical operators, so that's an easy case to make. is punctuation, but let's see what others think. If it gets a few other votes I think we can add this.

@tkelman tkelman added the parser Language parsing and surface syntax label Aug 19, 2016
@andyferris
Copy link
Member

is frequently used in superscript position... is there some way of doing this in Unicode?

@tkelman
Copy link
Contributor

tkelman commented Aug 22, 2016

I think the way is "petition the Unicode committee and hope it gets included in Unicode N+1" ?

@cstjean
Copy link
Contributor Author

cstjean commented Aug 22, 2016

@TotalVerb For what, variables in pattern-matching? $ is for plugging in values. MacroTools does the inverse: it extracts parts of an expression tree.

I want to build a tree with variables in it, and manipulate the tree. Right now it looks like tree = Node(1, 2, Node(5, Var(:x))). I would prefer tree = Node(1, 2, Node(5, ⨹:x)). I can use a macro in this particular case, so it's not the end of world. If I wanted a concise binary operation though, I would have plenty of unused, exotic operators to choose from ⨩ ⨪ ⨫ ⨬ ⨭ ⨮ ⨹ ⨺ ⩁ ⩂ ⩅ ⩊ ⩌ ⩏ ⩐ ⩒ ⩔ ⩖ ⩗ ⩛

@jebej
Copy link
Contributor

jebej commented May 8, 2017

Is there any way to make the dagger operator parsable as a variable name? Right now it's just invalid.

@JeffBezanson
Copy link
Member

Yes, definitely, but we would need to decide on its syntax --- i.e. does it parse as an identifier, or some kind of operator?

@jebej
Copy link
Contributor

jebej commented May 8, 2017

Personally, I would use dagger as an identifier (ie part of a variable name). The complex transpose already has a symbol for it so it makes little sense to just have † do the same operation.

The exact use case I have is to store the result of something like this:

a†a = a'*a 

@StefanKarpinski
Copy link
Member

That seems like a nice usage well aligned with how we already allow superscript integers and such.

@stevengj
Copy link
Member

stevengj commented Oct 6, 2017

Also, the most sensible meaning for a postfix operator would be adjoint, and we already have a postfix adjoint operator.

@chakravala
Copy link
Contributor

chakravala commented Oct 6, 2017

Hi, I didn't know about this issue but I found it after posting on discourse

I think it would be really great if people could define their own unary operators. Unary operators aren't so uncommon in mathematics.

Perhaps, a special character could be used in conjunction in order to help the parser determine that it is a unary operator. For example, `! could be factorial so that one couuld do 5`! and then one could define their own unary operator, each marked by `. Another thing could be to have both left-handed and right-handed unary operators.

For example factorial would be right-handed as in 5`! but if it was defined as a left-handed it could be written as !`5.

Not saying that ` is the right character for this, but it's just an idea that some sort of syntax like that might help in clarifying what is a unary operator and what is not, to help enable people to define their own unary operators for whatever they need.

@stevengj
Copy link
Member

stevengj commented Oct 6, 2017

@chakravala, the discussion of custom unary operators is very similar to the discussion of custom infix operators — see #16985. It's a bit of a rat's nest when you get into syntax details.

@jebej
Copy link
Contributor

jebej commented Jun 10, 2018

I would like to add \dagger to be a valid part of a variable name. Where would I do that?

@stevengj
Copy link
Member

@jebej, you would modify here.

@jebej
Copy link
Contributor

jebej commented Jun 11, 2018

Should I just add it at the end of line for primes?

(wc >= 0x2032 && wc <= 0x2037) || wc == 0x2057 || wc == 0x2020 ||

@rjkat
Copy link

rjkat commented Oct 22, 2018

FWIW I’d like to have and from Kleene algebra, but can also see the sense in keeping the number of operators to a minimum.

@StefanKarpinski
Copy link
Member

StefanKarpinski commented Oct 22, 2018

The ship has definitely sailed on "keeping the number of operators to a minimum"—I don't think that's ever going to be the stance. I think that if the case can be made for any operator having a standard syntax and precedence that fits in with the way Julia is parsed, we're happy to support it. The issue with unary operators is more that they're a bit weird syntactically than that we don't want more operators.

@kauesena
Copy link

I think a postfix unary operator to implement transpose or permutedims is really missing. A superscript T or t is almost universally adopted as notation for transposition without conjugation in mathematical texts. However, the Unicode symbol is currently allowed as part of variable names, and making it the operator would be a breaking change... (One I'd happily support.) But perhaps there is another good symbol which isn't yet allowed which could be used.

@Jollywatt
Copy link
Contributor

Jollywatt commented Sep 30, 2022

A superscript T or t is almost universally adopted as notation for transposition

@kauesena By the way, we can currently do this:

julia> var"'ᵀ"(a) = transpose(a)

julia> [im, 1]'1×2 transpose(::Vector{Complex{Int64}}) with eltype Complex{Int64}:
 0+1im  1+0im

Discussion

@Will-Hendrix
Copy link

if we're creating a list of desired unary operators, adding the cross matrix as a postfix operator for LinearAlgebra would be nice:
×(v) = [0 -v[3] v[2]; v[3] 0 -v[1]; -v[2] v[1] 0]

@stevengj
Copy link
Member

@Will-Hendrix, see PSA: Julia is not at that stage of development anymore — any operator that is currently parsed as binary (like ×) will not be changed to unary in 1.x (and likely never).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
parser Language parsing and surface syntax
Projects
None yet
Development

No branches or pull requests