Julia included in Oreilly's "Emerging Programming Languages" report (June 2019)

Makes sense. I have a lot more experience using standard libraries than maintaining them, so I probably just lack the perspective to recognize the problem. I suppose, like most things, there’s a balance to be struck here. In my experience, Python projects tend to be easier to maintain over a long period vs Ruby projects (to say nothing of JavaScript and the NPM nightmare) because they rely on fewer external dependencies. Standard library batteries may be “worse” in a lot of ways, but they have the benefit of being a known quantity that’s always there.

Of course, there are rumblings among the Python core devs at the moment about majorly downsizing the standard library and breaking a lot of it into a “core” package set which is maintained separately and can be added à la carte because the current size of the Python standard library is beginning to become untenable. Maybe something for Python 4.

Returning to syntax, for me, the current amount of syntax in Julia is a decent balance. It could be less, but it’s still manageable, and if the rate of growth of syntactic forms has slowed (like, hopefully to something barely more than stopped) as you say, I guess there’s no problem.

As someone who occasionally uses Perl, it’s possible that I just have bit of “PTSD” (so to speak–I don’t mean to trivialize the actual medical condition) about large syntaxes with a lot of subtle semantics. The words “Julia is an enormous language” just kind of exacerbated the paranoia I already have about Julia slowly turning into Perl.

2 Likes

That is a short for the form for k = 1:N that for many of us (those coming from Matlab, which is the original inspiration of Julia syntax) is the natural form of expressing a loop. for k in x came later (if I remember well). Anyway, this was discussed some 5 years ago.

5 Likes

Maybe “additional” wasn’t the right word. What I meant was that they are duplicates in terms of functionality. Either form would be fine with me, it’s just weird to have both. I suppose it’s for historical reasons; i.e. originally based on Matlab, but added in to be helpful to people more used to Python, Ruby and JavaScript. Either form is fine with me, but supporting both… ech.

I think the best course is just to ignore the one you don’t use for now, and participate in the discussion for 2.0, which is the earliest point this can be removed. Even if one considers this a wart, it is simply not a high priority one.

Also, it serves as a prime example of how you are stuck with things once they are in Base. :wink:

2 Likes

As a mainly Matlab programmer for the last two decades, I really dislike that spelling. The first time I saw for i in 1:N, I immediately thought “that makes so much more sense.”

7 Likes

Some of your examples, such as map and , and then I misremembered ChrisRackauckas’s post as being yours.

Due to how powerful generic concepts are in Julia, everything you add to the language gets multiple possible applications. Consider .... If that was special syntax for use inside array brackets, [], then that would perhaps be too much syntax. But that’s not what it’s for, it just happens to work that way as a side effect. The more powerful and composable concepts become, the more you get a proliferation of ways of doing things, just by the law of unintended consequences.

If you want very much to avoid multiple ways of spelling things, you end up having to impose artificial limitations, and making the language less consistent. In languages with less powerful generics, you don’t get that problem to the same degree.

3 Likes

I more or less agree (though I want using M: f too) and I only use Module.function for extending functions. But I can see someone wants import M: f for extending a lot of (say) binary operators in a lot of ways.

Another way to encourage/enforce uniformity in the syntax is a code formatter (with (almost) no configuration options). These days I really enjoy using black in Python projects and I remember gofmt was great too. I know Julia has DocumentFormat.jl but I don’t know if it converts for x = xs to for x in xs.

4 Likes

Personally this really annoyed me, I format my code so I can easily read it, but when the formatter has it’s own way to format…it just annoys me. I was forever disabling the go formatter in the editor, which for some reason always loved to re-enable it.

1 Like

This does not make sense to me. Can anyone explain why is it giving this output?

Scalars are iterable, with length 1, and


julia> length(zip(1, 1:3))
1

This, of course, does not make sense :wink:, but is surprisingly tricky to get rid of now.

1 Like

in many languages, map only takes one iterable as the argument, but in Julia, it can take a list of iterables, but it zips them first and turns that into separate arguments for the function. That’s kind of cool.

Unfortunately, in Julia, even numbers are iterables of length == 1, so… bad stuff happens. broadcast has some trait magic to work around this insane behavior. map does not.

2 Likes

And so are 1:2 and 1:5, but

julia> map(+, 1:2, 1:3)
ERROR: DimensionMismatch("dimensions must match")

julia> map(+, 1:5, 1:3)
ERROR: DimensionMismatch("dimensions must match")

julia> map(+, 1:3, 1:3)
3-element Array{Int64,1}:
 2
 4
 6

julia> map(+, 1, 1:3)
1-element Array{Int64,1}:
 2

So it seems inconsistent to me that map(+, 1, 1:3) does not throw DimensionMismatch exception like 1:2 and 1:5 do.

1 Like

Wow. This, I didn’t know and cannot explain.

edit: Looks like map doesn’t use zip internally

It falls back to Base.Generator which does.

1 Like

Actually I would say that for Julia learners a bigger surprise usually is:

julia> map(+, [1 2], 1:3)
2-element Array{Int64,1}:
 2
 4
4 Likes

Just FWIW, the fact that numbers act like 0-dimensional arrays (that is, they’re iterable, indexable, and have axes) means that broadcast does not need to do anything special — in fact it makes broadcasting more consistent, not less. I agree that it’s not ideal in other situations, but it is what it is.

As far as map not ensuring that its arguments are the same lengths, I call that a bug: #13361.

8 Likes

these examples are making my body hurt.

2 Likes

Here we have a delicate thing that is related to how zip works:

julia> collect(zip(1:3, 1:5))
ERROR: DimensionMismatch("dimensions must match")

but

julia> for v in zip(1:3, 1:5)
       println(v)
       end
(1, 1)
(2, 2)
(3, 3)

and I always thought this was intended.

EDIT: but I agree that it is natural to expect that map always checks that the dimensions match.

2 Likes

map accepting multiple arguments in this way is quite traditional in the lisp world. Allowing different-length arguments and taking the prefix is too, but slightly more controversial. Some people insisted on giving an error in at least some cases though, leading to the current inconsistent state, which is very frustrating. We should remove that error.

Quick aside on the amount-of-syntax thing: it’s true that we have many syntax forms, perhaps too many, but I don’t think we are adding more at a high rate. Almost all the syntax you mentioned has been there since v0.1. I agree it would be nice to deprecate for x = y in v2.0; it really doesn’t make sense.

19 Likes