-1

And how can I define my own types of variables/objects to behave with the provided operations in python?

Can I do this without having to create my own object classes and operators as a separate and distinct entity? I dont mind having to create my own object class (thats a given), but I want it to integrate flawlessly with the already existing constructs. So emphasis on my wish to avoid "separate and distinct".

Im trying to create a quaternion object class. I want to define a 1i and 1k that are distinct from 1j.

And yes, a package might already exist; this is purely academic and for my own programming practice and understanding. Im trying to extend what is already there, and not build something that is distinct and separate.

I already do class objects but unfortunately they require a redefinition of the basic operations in order to make use of them, and even then I have to "declare" these objects before I can use them, quite unlike '1j'.

I hope I am clear with my intent. The end result of a quaternion is not my intent; it is the types of methods and objects and generalizations Im trying to figure out how to do, to extend and make use of what is already built into python.

It seems to me whoever built numpy and cmath have already been able to achieve this endeavor.


Thanks to the commentary below. I now have the vocabulary to express my intent better.

Im trying to add new features to Pythons SYNTAX.

If anyone can offer resources on how to do this, Id appreciate it.

  • What do you mean by "separate and distinct"? The built-in complex number class is already "separate and distinct" from other numeric types. If you want to create your own syntax, that's going to require you to fork the CPython source code, which is generally a much worse option than simply accepting that you're not going to be able to use `1i` and `1k` syntax. – user2357112 Aug 30 '18 at 18:24
  • Are you asking if you can modify python _syntax_ so that something like `1i` would be valid? If so, then you'll basically need to write some sort of pre-processor that will transform your source code before you ever feed it to Python ... – mgilson Aug 30 '18 at 18:24
  • (Also, `1j` corresponds to complex `i`, not quaternion `j`, so defining `1i` and `1k` would cause confusion separate from the syntactical issues.) – user2357112 Aug 30 '18 at 18:26
  • Yes. Thank you guys. Vocabulary of Python. HAHA. I want to modify Python syntax. – CogitoErgoCogitoSum Aug 30 '18 at 18:26
  • Try typing `1i` or `1k` into a Python interpreter; you'll get a `SyntaxError`, which is something you cannot possibly change from Python code. Any syntax that produces something like a `ValueError` or `NameError` is something you could possibly influence, for example you could define a constant `k` such that `1*k` gives your desired value. – jasonharper Aug 30 '18 at 18:29
  • @user2357112 I beg to differ. Im a mathematician. There is no distinction between i and j and k. Watch: a+bi, a+bj, and a+bk, are all complex numbers existing in their own distinct orthogonal complex planes (each 2-dimensional), embedded in a larger 4 dimensional space, and each passing through the origin. They only differ when used together as a quaternion. Used separately there is no need to quibble over which to use for complex numbers because you can use any. This is a mathematical fact a programmer would necessarily have to be aware of. – CogitoErgoCogitoSum Aug 30 '18 at 18:29
  • Each of a+bi, a+bj, and a+bk behave exactly the same way as complex numbers. They only behave differently, like quaternions, when you use a combination. This also resolves the controversy between engineers and mathematicians. We dont have to debate about "differences in convention" if we simply acknowledge that we are working in different complex planes within quaternion space. – CogitoErgoCogitoSum Aug 30 '18 at 18:36
  • @CogitoErgoCogitoSum: If people try to mix built-in complex math and quaternions, they're going to expect `cmath.sqrt(-1)` to be i, not j, just like they're not going to expect it to be -k. There may be many embeddings of the complex plane in the quaternions, but people have expectations about the default choice. – user2357112 Aug 30 '18 at 18:41
  • 1
    @CogitoErgoCogitoSum: It's not clear to me what you're asking - do you want to create a fork of Python that supports the syntax `1i`, `3.4k`, etc? (In which case other people wouldn't be able to make use of the new syntax unless they also adopted your fork of Python instead of the usual one.) Or do you want to try to persuade the Python core developers to change the language, so that e.g., your desired syntax is supported in Python 3.8, and is then available to everyone? – Mark Dickinson Aug 30 '18 at 18:50
  • 1
    @CogitoErgoCogitoSum: If you just want to change Python's syntax for your own amusement, and don't need to share the changes with others, then you might start with https://devguide.python.org/grammar/. It's a bit terse, but an internet search also turns up a couple of tutorials on extending Python's syntax. – Mark Dickinson Aug 30 '18 at 18:51
  • @user2357112 The dilemma you bring up is half-valid. But its moot. If you are using the cmath package to evaluate sqrt(-1) then you are already dealing with a complex number, not a quaternion, by definition. Thats what cmath is for. So you are stuck within a single complex plane by default and it doesnt matter which of i,j, or k you use as default. Like I said, each complex plane behaves the same on their own. Only when you employ "qmath.sqrt(-1)" is there going to be a dilemma. But guess what? Mathematicians working on pen and paper already face that dilemma. – CogitoErgoCogitoSum Aug 30 '18 at 18:55
  • Its not a programming issue, its a pure math issue. We can choose the default arbitrarily, perhaps?! – CogitoErgoCogitoSum Aug 30 '18 at 18:56
  • @MarkDickinson Thank you for that reference. Yes, I dont care if I share the code. I dont care if the developers adopt it or not. Its for my own education. – CogitoErgoCogitoSum Aug 30 '18 at 18:57
  • @CogitoErgoCogitoSum: Missing from that list is [Parser/tokenizer.c](https://github.com/python/cpython/blob/master/Parser/tokenizer.c), which would actually be the main place you'd need to change for the syntax. There'd also be the small matter of adding a new builtin type. – Mark Dickinson Aug 30 '18 at 19:01

2 Answers2

0

I see two options for you here:

  1. Change the Python syntax (fork CPython), there's a surprising amount of articles about how to do that.
  2. Build some kind of preprocessor like Mypy.

Either way it seems like too much trouble just to have a new literal value.

yorodm
  • 4,359
  • 24
  • 32
0

Python does not support custom operators nor custom literals.

A language that supports custom literals is C++ (since C++11 I believe), but it does not support custom operators.

A language that supports custom operators is, for example, Haskell.

If you want to add this feature to Python you'll have to take the Python sources, modify its grammar, modify the lexer/parser and more importantly the compiler.

However at that point you just create a new language, which means you broke compatibility with python.

The easiest solution would simply be to write a simple preprocessor that replaces some simple syntax with an expanded equivalent. For example:

sed -i 's/(\d)+\+(\d+)i/MyComplex(\1, \2)/g' my_file.py

Then you can execute the preprocessor in the build step of your library/application.

This has the advantage of letting you write the code you want, but when you ship it/use it it is translated into normal python, keeping 100% compatibility with existing installations.

I believe using import hooks it would be possible to avoid having to ship the preprocessed version of your library... basically the preprocessor could be included in the import step and done on the fly. This would avoid having to deal with temporary preprocessed files.

The only requirement would be that people that need to use your library will have to install the import hook someway.

Bakuriu
  • 98,325
  • 22
  • 197
  • 231