# Why are there all these strange stumbling blocks in Julia?

You mean things like "abc"^3 == "abcabcabc"? Yes.

Conceptually, if not practically, I would love "start" \"startmiddleend"/"end" == "middle"

5 Likes
julia> oneunit(String) * "ab"
"ab"


The practical example I have in mind is that, because regular expressions follow a Kleene algebra in which concatenation is represented by (\cdot), then because we have chosen * for concatenation we can implement operations on regular expressions and they will be consistent with their theoretical properties. For example, we could implement an alternation operator for regular expressions using + as is common in formal language theory (or another + like operator such as |).

If we did implement more operators for regular expressions, itâd be a crying shame if string operations were dissimilar and had different operator precedence.

2 Likes

I have already expected this answer. I know Julia is not and should not be a Python clone, but my underlying question is: why reinvent things that worked easily and intuitively in another language? For the most part, @DNF has given understandable answers to my specific points.

Frankly this example and oneunit(String) * "ab" are not very convincing because they would work in the exact same way with addition: "hello" * 5, zerounit(String) + "ab". On the other hand I am fully convinced by "start" \ "startmiddleend" / "end", because it exploits fully the fact that multiplication is not commutative and has two inverses. And by the example with regexpâs and commutativity. Thanks to @gustaphe and @uniment, I was glad to see your examples.

Too bad these two are only suggestions and do not work in practice. It would have been great to have an example of a currently existing practical feature of the language / standard library which is enabled by the choice of * rather than +; if you have such an example I am all ears.

4 Likes

I see this from a more reality-based perspective, if I have two apples and add one, I have three apples. I can also multiply apples times 2, then I have four apples. Therefore it is difficult for me to understand this *, because I cannot multiply apples among each other and do not expect to get the result of an addition. This is very unintuitive for me.

1 Like

âelifâ simply because it is understood just as well, but is shorter.

This has been said before, but once again:

1. There are many other languages (you just happen to have a strong Python bias).
2. âeasily and intuitivelyâ is largely subjective and heavily influenced by the language youâre coming from.

For example, elseif is âeasy and intuitiveâ in MATLAB, which also uses 1-based-indexing.

8 Likes

I have programmed Java before Python. So âyesâ I found the Python syntax a great relief from the bloated Java syntax. I donât stick to a language like a tribe I have to defend, I see what is practical and what is not, so these two sentences are relatively independent.

If I would ask my girlfriend (who knows nothing about programming) what elif means she might have no clue.

Anyways, Iâm going to stop here, because such a syntax discussion is neither fun (at least not for me) nor useful (it is what it is and it wonât change.).

8 Likes

âelifâ is very quick to understand and easy to remember, but youâre right, of course Iâll still learn Julia because the language just has so many other advantages!

2 Likes

@Sandjan, I think your questions are reasonable and @DNFâs answer (Why are there all these strange stumbling blocks in Julia? - #2 by DNF) was a straightforward response that (you, presumably) acknowledged. So in a sense perhaps not much else needs to be said.

But I do care about how âlearnableâ Julia is and so these discussions are relevant. Areas of Julia that concern me most are things like the stacktraces and how complex types can occasionally become in Julia, but I notice that none of these made your list. Itâs useful to hear the perspective of a newcomer, so thanks.

One point I can address directly, as an amusing discovery I made within my first 5 minutes of learning Python (unlike you, I learned Python after Julia, and perhaps unsurprisingly I have your experience in reverse when I look at Python code). This example illustrates how two sensible âconveniencesâ can in fact lead to inconsistency:

In Python,

>>> int("4")       # seems fine
4
>>> float("3.2")   # seems fine
3.2
>>> bool("False")  # huh?
True


Thereâs a good reason for the behavior of the last line: unlike Julia, Python automatically tests âtruthinessâ (which some might argue is an advantage of Python) and for containers truth means ânon-emptyâ. So because "False" is not the empty string, itâs True. But obviously that result is a trap if you expect it to parse the string.

In general, I find Python slightly too willing to just mush forward, and often Iâd rather it just throw an error. Itâs not as if Julia doesnât have itâs own amusing/concerning list of âwat?sâ, but at least in this particular case I think Juliaâs increased pickiness saves you from a trap.

Anyway, I think itâs great that youâre paying attention to what aspects of Julia make it easier or harder to learn & use, and Iâd be curious how your perspective on this evolves with increased familiarity with the language.

49 Likes

How come these âwatsâ do not break regular Julia code?

Is it because they are âweirdâ patterns one rarely stumbles into?

For the same reason that these wats donât break regular python code. These Most are just weird edge cases that you pretty much never see in the wild.

Edit: I did not want to dismiss the possibility that there are bugs happening because of these behaviors. But itâs not worse than for any other language IMHO. To elaborate, from the list linked by Tim Holy I consider only one entry (precedence of the range operator) a common footgun & two more entries as possible candidates for bugs that may appear in the wild

details

(typo changing _ to - and accidentally shadowing Base.:- and maybe ambigous float literal juxtaposition if somebody manages to combine questionable variable naming, questionable whitespace placement and complete unawareness of scientific notation)

As always, itâs good to be aware of the edge cases of any language you work with.

5 Likes

The parsing precedence of : and of &/== causes bugs all the time. Others like fld/div mentioned above may cause bugs as well.

I tend to be very liberal in my use of parentheses for this reason. I prefer being explicit.

8 Likes

The answer by @DNF is straightforward, every language has its own choices and doesnât have to be a copy of any other language. However, I find two valid points in the OP:

I find this truly annoying. I donât mean specifically parsing, I mean something like truncated integer division. In C and Fortran, I could do for example int x = 5.2 / 2 to get x = 2. To do the same thing in Julia, I have to write x = trunc(Int, 5.2 / 2), there is no straightforward function/symbol for truncated integer conversion, and Int(2.6) doesnât help here. Whereas in C and Fortran you get it implicitly for free based on the types of variables.

Again, this is also a valid point. Using * for concatenating two strings is completely unintuitive, regardless of âcommutativityâ or any other algebraic property. No one (I assume) would think of stacking two strings beside each other using * instead of +. Simplicity matters, but Julia, at many times, chooses pickiness over simplicity.

3 Likes

This is only about familiarity, not intuition. Intuitively, concatenation is closer to multiplication than to addition, in mathematics that is even how you normally write multiplication: by concatenating symbols. xy is the product of x and y.

21 Likes

I think this is an âabstract algebraâ v colloquial usage issue.

For non-mathematicians âxâ concatenated with âxâ gives âxxâ and its natural to think of this as âtwo xâsâ, hence + feels right.

In abstract algebra * is just an operation that satisfies different properties (I think âfree groupâ and âwordâ are relevant terms). Since concatenation satisfies these properties it makes sense to use *.

Since Julia was designed with scientific computing (or numerical mathematics) in mind it makes a lot of sense they went with the mathematical version.

11 Likes

Isnât it unusual for a * to have measure(s * t) == measure(s) + measure(t), where measure is length?