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

unicode operators #552

Closed
Tracked by #55344
rtzui opened this issue Mar 9, 2012 · 14 comments · Fixed by #6582
Closed
Tracked by #55344

unicode operators #552

rtzui opened this issue Mar 9, 2012 · 14 comments · Fixed by #6582
Labels
speculative Whether the change will be implemented is speculative unicode Related to unicode characters and encodings

Comments

@rtzui
Copy link

rtzui commented Mar 9, 2012

I think that infix functions would be nice. in haskell you can call +(1,3) (as in julia or lisp). You can write it infix 1 + 3, but you can also force infix f(a,b) ==a 'f' b. (actually not ', but rather +0060)
I would be really cool if certain range of unicode could be used infix aswell, so one could define , use it like ∈([1,2,3],[2,3,9,10]) lisp style, or more intuitive [1,2,3] ∈ [2,3,9,10].

define ≟(a,b)
    a==b
end

>1≟2
false

>2≟2
true

define ∈(a,b)
 #code
end

>1∈[1,3,4]
true

And maybe a infix "keyword" would be cool as well:

function foobar(x,y)
 #code
end

5 ⍚foobar "qwertz" would be the same as foobar(5,"qwertz")
functions with names that contain nothing but +-*/%!§$?<>=#~ and a certain unicode range would be infix by default and would not need that symbol.

A nice thing that could be done would be

function >>=(a,b)
  if b
    a(b)
  end
end
@StefanKarpinski
Copy link
Member

This could certainly happen at some point. The ∈ is a particularly good candidate. For now though, it's a pretty low priority and can always be added later. Another thing that would be nice is adding unicode aliases for multi-character operators:

  • ≤ for <=
  • ≥ for >=

and so on.

@JeffBezanson
Copy link
Member

We won't do the haskell arbitrary infix thing a 'f' b, since we're out of ascii characters, but I think we can do the rest of it.

@marcusps
Copy link
Contributor

marcusps commented Mar 9, 2012

In some domains this can be extremely helpful. I do a lot of quantum mechanical calculations, and so end up doing a lot of calculations with tensor product of matrices. Having ⊗ [Unicode 'CIRCLED TIMES' (U+2297)] would be preferable to 'kron', and having ⊕ [Unicode 'CIRCLED PLUS' (U+2295)] could also be very convenient.

Scala allows any function to be used in infix form, I think (or at least it is very flexible and more readable than Haskell), but this would require bigger changes to Julia.

One possibility if to allow only characters in the Mathematical Operators block of the Unicode standard to be used an infix operators, aside from the standard ones.

@pao
Copy link
Member

pao commented Mar 9, 2012

I'd love to know where I defined ⊕, but I'm not sure how to grep for it without copying and pasting it. I wouldn't know how to type it, and even if we had editors with automatic replacements, I'd have to look up how to enter the right characters to get the replacement.

While it's very pretty and I get that it's helpful when comprehending code for some domains, I worry that it could be a beast to edit. See also: the APL keyboard. At least then you can look at the keyboard as a reference.

@StefanKarpinski
Copy link
Member

@pao: this is exactly why I think this should remain "future possibilities" for now. One idea I've thought about is to have a tool that will translate any code to an equivalent pure-ascii version and back to using Unicode for operators. Could also have a special grep that knows how to look for operators in either form (i.e. knows that they're equivalent). That's obviously very Julia-centric, but in a sophisticated web-based development environment, it would be entirely possible.

@marcusps
Copy link
Contributor

marcusps commented Mar 9, 2012

There is the danger of devolving into APL, but at the same rate I don't think that e.g. numpy's solution of writing A.dot(B) for matrix multiplication of narray is something that should be encouraged.

In the case of tensor/Kronecker products, writing kron(A,kron(B,C)) is much more awkward than A ⊗ B ⊗ C.

One possibility to avoid the APL/Unicode problem is to use LaTeX type notation for infix operators, and have the IDE change it automatically to the unicode op, e.g. A \kron B \kron C. This way it is always searchable and familiar for people who write papers with Mathematical notation.

@StefanKarpinski
Copy link
Member

Definitely agree that A.dot(B) isn't very nice. That's why Julia supports all of Matlab's operators, and then some. In the case of kron, one could also write kron(A,B,C) which, while not as fancy looking as A ⊗ B ⊗ C, is still pretty readable.

One possibility to avoid the APL/Unicode problem is to use LaTeX type notation for infix operators, and have the IDE change it automatically to the unicode op, e.g. A \kron B \kron C. This way it is always searchable and familiar for people who write papers with Mathematical notation.

This assumes a non-existent IDE. Also, we're certainly not going down the Fortress path where you need some special WYSIWYG IDE for coding in the language to be reasonable. A tool that can translate to and from ASCII non-infix form and Unicode infix form is different because it's not an IDE, it's just a source translation tool.

@JeffBezanson
Copy link
Member

I have an emacs input method that auto-converts various backslash sequences to unicode characters. I could check it in to contrib, or make it part of julia-mode if people want ;)

@ViralBShah
Copy link
Member

I would prefer not introducing any of these unicode characters. I don't always have access to emacs when I edit julia! One could always make these optional, so that you don't have to use them - but others start using them in their codes, and it makes it difficult to work on code written by others.

@JeffBezanson
Copy link
Member

JUST USE EMACS DAMMIT
:P

@o-jasper
Copy link

o-jasper commented Oct 4, 2012

If you do this, please make all Expr results from infix operations the same. Compare :(a+b+c) with :(a|b|c), if you write macros have to deal with that. Note: for stuff that isn't associative, where the parentheses happen matters.. The programmers fault for not putting parenthesis in, (s)he is making ambiguous.

@salehqt
Copy link

salehqt commented Mar 12, 2013

I think the idea of Unicode operators is very neat, it might not be very easy to type, but it enhances readability of the code. Considering that 80% of development time is spent in debugging, having a readable code is very important (especially in numerical packages).

Contrary to what people mentioned in the discussion, problem of typing Unicode characters does not affect the language itself, Julia supports Unicode input so there is no problem there. One can always have ASCII aliases for all of the Unicode names, or better, make the ASCII name the primary form and have a Unicode name for convenience. (e.g. define the kron(a,b) function and then define the unicode operator as ⊗=kron)

Typing unicode characters is does not introduce inconsistency. I think that should be left to the user. I just changed my keyboard layout to use AltGr to type Unicode operators and Greek letters. It is also possible to have an IDE to convert LaTeX sequences (I did that with Geany). But none of these affect the implementation of operators.

I tried a small hack and it worked. I will post my code once I implement some of the operators.

@alanedelman
Copy link
Contributor

This is an old list, but I just had to add that for the last few days I've been
using:
√(x)=sqrt(x)
and I don't know how I lived without it.

@JeffBezanson
Copy link
Member

Still have to decide what to do with the full set of unicode operators.

KristofferC pushed a commit that referenced this issue Aug 4, 2018
* Refactor: APIOptions should be a dictionary

* Fix `do_activate!` interface

* Update tests: APIOptions is a dictionary

* Allow more flexibility for REPL `do_<>` functions
KristofferC pushed a commit that referenced this issue Aug 4, 2018
* Refactor: APIOptions should be a dictionary

* Fix `do_activate!` interface

* Update tests: APIOptions is a dictionary

* Allow more flexibility for REPL `do_<>` functions
KristofferC pushed a commit that referenced this issue Aug 4, 2018
* Refactor: APIOptions should be a dictionary

* Fix `do_activate!` interface

* Update tests: APIOptions is a dictionary

* Allow more flexibility for REPL `do_<>` functions
KristofferC pushed a commit that referenced this issue Feb 11, 2019
* Refactor: APIOptions should be a dictionary

* Fix `do_activate!` interface

* Update tests: APIOptions is a dictionary

* Allow more flexibility for REPL `do_<>` functions
ViralBShah pushed a commit that referenced this issue Aug 12, 2024
Stdlib: SparseArrays
URL: https://github.com/JuliaSparse/SparseArrays.jl.git
Stdlib branch: main
Julia branch: master
Old commit: e61663a
New commit: 55976a6
Julia version: 1.12.0-DEV
SparseArrays version: 1.12.0
Bump invoked by: @ViralBShah
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaSparse/SparseArrays.jl@e61663a...55976a6

```
$ git log --oneline e61663a..55976a6
55976a6 Keep sparse solvers docs as before (#552)
95fd7ff Missing space in error message (#554)
b8a13ef implement in-place `ldiv!` for Cholesky factorization (#547)
1527014 Do not use nested dissection by default. (#550)
```

Co-authored-by: Dilum Aluthge <[email protected]>
lazarusA pushed a commit to lazarusA/julia that referenced this issue Aug 17, 2024
…aLang#55469)

Stdlib: SparseArrays
URL: https://github.com/JuliaSparse/SparseArrays.jl.git
Stdlib branch: main
Julia branch: master
Old commit: e61663a
New commit: 55976a6
Julia version: 1.12.0-DEV
SparseArrays version: 1.12.0
Bump invoked by: @ViralBShah
Powered by:
[BumpStdlibs.jl](https://github.com/JuliaLang/BumpStdlibs.jl)

Diff:
JuliaSparse/SparseArrays.jl@e61663a...55976a6

```
$ git log --oneline e61663a..55976a6
55976a6 Keep sparse solvers docs as before (JuliaLang#552)
95fd7ff Missing space in error message (JuliaLang#554)
b8a13ef implement in-place `ldiv!` for Cholesky factorization (JuliaLang#547)
1527014 Do not use nested dissection by default. (JuliaLang#550)
```

Co-authored-by: Dilum Aluthge <[email protected]>
KristofferC added a commit that referenced this issue Aug 26, 2024
Backported PRs:
- [x] #54962 <!-- Add timing to precompile trace compile -->
- [x] #55180 <!-- compress jit debuginfo for easy memory savings -->
- [x] #54919 <!-- Fix annotated join with non-concrete eltype iters -->
- [x] #55013 <!-- [docs] change docstring to match code -->
- [x] #55017 <!-- TOML: Make `Dates` a type parameter -->
- [x] #54033 <!-- Fix a bug in `stack`'s DimensionMismatch error message
-->
- [x] #55242 <!-- fix at-main docstring to not code quote a compat box
-->
- [x] #55261 <!-- Make `jl_*affinity` tests more portable -->
- [x] #54736 <!-- specificity: ensure fast-path in `sub/eq_msp` handle
missing `UnionAll` wrapper correctly. -->
- [x] #55299 <!-- typeintersect: fix bounds merging during inner
`intersect_all`. -->
- [x] #55302 <!-- Add `lbt_forwarded_funcs()` to debug LBT forwarding
issues -->
- [x] #55148 <!-- Random: Mark unexported public symbols as public -->
- [x] #55303 <!-- avoid overflowing show for OffsetArrays around typemax
-->
- [x] #55317 <!-- Restrict argument to `isleapyear(::Integer)` -->
- [x] #55327 <!-- Profile: Fix stdlib paths -->
- [x] #55330 <!-- [libblastrampoline] Bump to v5.11.0 -->
- [x] #55310 <!-- Preserve structure in scaling triangular matrices by
NaN -->
- [x] #55329 <!-- mapreduce: don't inbounds unknown functions -->
- [x] #55356 <!-- Profile: close files when assembling heap snapshot -->
- [x] #55371 <!-- Fix tr for block SymTridiagonal -->
- [x] #55307 <!-- Make REPL.TerminalMenus public -->
- [x] #55362 <!-- inference: fix missing LimitedAccuracy markers -->
- [x] #55306 <!-- AllocOpt: Fix stack lowering where alloca continas
boxed and unboxed data -->
- [x] #55395 <!-- fix #55389: type-unstable `join` -->
- [x] #55226 <!-- re-add `unsafe_convert` for Reinterpret and Reshaped
array -->
- [x] #55405 <!-- handle unbound vars in NTuple fields -->
- [x] #55365 <!-- ml-matches: ensure all methods are included -->
- [x] #55428 <!-- codegen: move undef freeze before promotion point -->
- [x] #55419 <!-- `stale_cachefile`: handle if the expected cache file
is missing -->
- [x] #55470 <!-- Add push! implementation for AbstractArray depending
only on resize! -->
- [x] #55483 <!-- fix hierarchy level of "API reference" in `Dates`
documentation -->
- [x] #55268 <!-- simplify complex atanh and remove singularity
perturbation -->
- [x] #55441 <!-- fix Event to use normal Condition variable -->
- [x] #55413 <!-- subtyping: fast path for lhs union and rhs typevar -->
- [x] #55492 <!-- build: add missing dependencies for expmap -->
- [x] #55507 <!-- Fix fast getptls ccall lowering. -->
- [x] #55424 <!-- add missing clamp function for IOBuffer -->
- [x] #55504 <!-- Update symmetric docstring to reflect the type of uplo
-->
- [x] #55107 <!-- Make the memory GEP an inbounds GEP since the bounds
check has happened somewhere else -->
- [x] #55411 <!-- Vendor the terminfo database for use with
base/terminfo.jl -->
- [x] #55452 <!-- Do not load `ScopedValues` with `using` -->
- [x] #55407 <!-- Remove deprecated non string API for LLVM pass
pipeline and parse all options -->
- [x] #55461 <!-- 🤖 [master] Bump the StyledStrings stdlib from d7496d2
to f6035eb -->
- [x] #55433 <!-- Backport #55407
to 1.11 -->
- [x] #55225 <!-- [1.11 backport] trace-compile: don't generate
`precompile` statements for OpaqueClosure methods (#55072) -->
- [x] #55212 <!-- Make `Base.depwarn()` public -->
- [x] #552
- [x] #55052 <!-- Fix `(l/r)mul!` with `Diagonal`/`Bidiagonal` -->
- [x] #55251 <!-- Restrict binary ops for Diagonal and Symmetric to
Number eltypes -->95 <!-- LAPACK: Aggressive constprop to concretely
infer syev!/syevd! -->
- [x] #55522 <!-- Fix tr for Symmetric/Hermitian block matrices -->

Need manual backport:
- [x] #55342 <!-- Ensure bidiagonal setindex! does not read indices in
error message -->

Contains multiple commits, manual intervention needed:

- [ ] #55336 <!-- codegen: take gc roots (and alloca alignment) more
seriously -->


Non-merged PRs with backport label:
- [ ] #55506 <!-- Fix indexing in _mapreducedim for OffsetArrays -->
- [ ] #55500 <!-- make jl_thread_suspend_and_get_state safe -->
- [ ] #55499 <!-- propagate the terminal's `displaysize` to the
`IOContext` used by the REPL -->
- [ ] #55458 <!-- Allow for generically extracting unannotated string
-->
- [ ] #55457 <!-- Make AnnotateChar equality consider annotations -->
- [ ] #55453 <!-- Privatise the annotations API, for StyledStrings -->
- [ ] #55443 <!-- Add test for upper/lower/titlecase and fix call -->
- [ ] #55355 <!-- relocation: account for trailing path separator in
depot paths -->
- [ ] #55220 <!-- `isfile_casesensitive` fixes on Windows -->
- [ ] #55169 <!-- `propertynames` for SVD respects private argument -->
- [ ] #54457 <!-- Make `String(::Memory)` copy -->
- [ ] #53957 <!-- tweak how filtering is done for what packages should
be precompiled -->
- [ ] #51479 <!-- prevent code loading from lookin in the versioned
environment when building Julia -->
- [ ] #50813 <!-- More doctests for Sockets and capitalization fix -->
- [ ] #50157 <!-- improve docs for `@inbounds` and
`Base.@propagate_inbounds` -->
- [ ] #41244 <!-- Fix shell `cd` error when working dir has been deleted
-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
speculative Whether the change will be implemented is speculative unicode Related to unicode characters and encodings
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants