Julia as first language

I would guess that most Julia users are not “programmers” by profession, they are scientists and researchers who happen to program a lot.

“Just get stuff done” is a slippery slope. It starts with a simple plot. Then you fit a simple statistical model. Then you code a bootstrap simulation to get an idea about the sampling error. Then you decide to estimate a more complex statistical model and turn to Bayesian methods… and pretty soon you find you are refactoring a 10k LOC codebase written for your project.

The idea you can just dip your toe in programming is an illusion. Coding skills are becoming indispensable for some fields. This does not mean that every researcher needs to write code, just that the team needs a few people who are comfortable with programming.


Right, and working scientists that happen to code a lot probably aren’t learning in an optimized way. As you say, they fall down the slippery slope of “get shit done.”

As I said

What I’m saying is that this kind of user is not going to pick the “best” language to learn from first principles, or even the language that has the best potential for long term productivity. They’re going to pick the language where they can get the most shit done the most quickly, and that’s most likely going to be the language that people around them (in their lab or in their department or in their field) are using, or the language that has the most “here’s how to make a scatter plot in {LANGUAGE}” hits when they google it.


I don’t disagree - I’m a huge Julia fanboy, and really never liked R. At the same time, I have many colleagues who are extremely productive is R without every learning anything about these object systems. They need to do analyses on data and make plots, and 85% of what they need is in tidyverse and the other 15% is in a handful of domain - specific packages that are already written for them.

And if I had an idea for a package and my goal was the widest reach in my field, I would probably take the time to learn one of those object systems and write it in R. Happily, that’s not my goal, so I never have to subject myself to that (query whether that’s not my goal because I’m unwilling to subject myself to that), but I can definitely understand people who make that determination.


I think the mantra: “This is open source, nobody owes anything to you, if you are not satisfied with anything - do it better yourself” is absolutely legitimate. On the other side, a novice generally can well identify the rough edges (which the long-time users are get accustomed to live with), but being a novice (s)he is not yet qualified to make an improvement.


I myself do programming at most 30% of my work time, of which 3/4 is LabVIEW, Julia is a hobby in part, but is a useful (or indispensable) tool for some tasks. I know some colleagues who know how to use Python or Matlab and use it occasionally, but mostly busy with some real things like writing grant proposals or having experiment running and students working. This is exactly the case of just dipping one’s toe into programming.

Similarly though, such a newcomer is also usually not yet equipped to make productive suggestions or demands about how these things should be improved. That’s why people often use the “please submit a PR” as essentially a way of dismissing such demands or suggestions – the demand or suggestion isn’t coherent, and lacks the wider necessary context to be productive.

Newcomers are very good at identifying painpoints, and we should absolutely listen when they tell us that they find something to be bad or not ideal. But when a newcomer shows up and starts suggesting a wide-scale course of action and set of projects people should take on without actually having the context or understanding to participate in those projects, I think the value is greatly diminished.


Julia, or rather a subset of it, could be an excellent first-and-only language for those not-CS students who currently are taught “some” language as an introduction into programming - engineers, economists, biologists, you name it… “Some” language being probably mostly Matlab or Python or maybe Java - not Scheme or Racket to my knowledge. Of these students, 50% to 90% will never program anything more complex that an Excel formula. But the rest constitutes an important part of the respective users community.

It is perfectly possible to get the things done - to write e.g. some statistical evaluation or some ODE based model - without knowing much about the Julia type system. The heavy lifting will be made by optimized packages anyway. Yes, maybe your program is not optimized and takes half a minute to finish instead of half a second - so what?

For teaching Julia as first-and-only I see “only” a few major obstacles. One is the workflow problem, to which there are a number of suggestions to improve the situation. Another is error messages, which (as of 1.9) is a no-go, except you are using Unitful (which is otherwise a great bonus for any computations with physical units), in which case it is an absolute no-go. Error message is the first thing the new user gets confronted with. One more problem is that the language currently is a fast moving target.

Ones these problems are solved one should start thinking about how to advertise Julia as an “easy-to-start language”, and how to introduce it to those “other” students.

1 Like

Yes I know. In fact, I wrote and taught an intro programming course for biologists :wink:.


On the other side, a novice generally can well identify the rough edges (which the long-time users are get accustomed to live with), but being a novice (s)he is not yet qualified to make an improvement.

That’s the whole pain of being a newcomer in a nutshell.

As a more experienced programmer, you experience organizational blindness, as all these little pain points become invisible to you.

The workarounds, that you use internally in your brain, and externally in the code, become second nature.

I recognize that every time, I actually go programming, and practice. I recognize, how I get blind to these issues, and how I make the same blind assumptions of what a newcomer is expected to understand - almost always without explicit notice - and this is exactly why I hold back with my practicing for so long.

The longer I was programming, the more it became apparent that I would only have to unlearn what I was already doing if I would encounter down the line, that it was suboptimal in the first place.

(I am already at a place, where I don’t know how to shape my code, if I don’t have sum types.)

Look at all these people, who say functional programming is so hard, only because they are used to object orientation and mutating state all over the place.

It’s literary the number one reason people give, why they would not a more functional style, and I think this is just a really sad state of affairs.

Just imagine physicist were saying “Newton is just soo convenient, and we are used to it, so better stay on that, and reject that Einstein dude with his theory. Like, how good could it be, that it warrants a change?”

I mean, that’s basically just us, the programming community.
And that is not the standard that any scientific community should set for itself.

The current top 10 most used programming languages, surely don’t comply with the scientific findings of the 70s.

The users of these languages often don’t even know about them.
And I think a huge part of that is “being used to” and not wanting to change.

Tldr: So I always thought, it’s more sensible to stay on the more modern path of language design, that incorporates these findings, and I always found languages, who put beginner friendliness as a second class citizen.

And even more worryingly, communities often did not even think consciously about this case.

As a newbie, you see exactly what is lacking, and you depend on others to make it for you.
Just like when you were a baby.

Still, we wouldn’t say babies should care for themselves :wink:
Or to not have them at all.

They are clearly our future.

1 Like

My experience with Julia…
Yes, it was fast.
Yes, it was easy like python.
However, with multiple dispatch, macros, etc, these are new concepts that was more than learning just a new language.
I think Julia is an easy to learn but high skill cap language.

1 Like

There is a difference between a programming language meant to be good as education (introduction to programming) and one that a beginner would like to start with because it is being actually used a lot and has lots of power.

As example of the first, I learned programming in Pascal. For fun I dabbled also in BASIC. But these languages had little use outside of teaching besides introducing you to for/while loops, functions, if/else and types, with a relatively clean syntax. C++ was used to teach me object-oriented thinking mainly.

Later I needed to program in C, IDL/PV-WAVE and Matlab/Scilab. Clearly the latter two (groups) offer lots of convenience by high-level functions and the power and motivation. But instead, you spend time learning what goes in and out of those functions and their keywords. You would not want a beginner to get distracted with those if he/she does not yet know the basic elements of a programming language.

Julia has great syntax and can teach basic programming concepts right from the start, much like Pascal, with access also to other paradigms. On top of that, the power of packages and speed for further motivation to keep using Julia.

When I switched to Julia, and wanted to use packages, I noted 2 things: the packages and its manager actually work right out of the box (my “Matlab” colleague trying to use Python for something is struggling to install dependencies), and you need to supply your data with the right type to functions (less of an issue in Matlab/Scilab). Once you start using types, you feel the power opening up, but it can start to feel overwhelming if exposed to all the surrounding functionality, which is at work under the hood in many packages.


Julia is the worst possible choice for starting out in programming!

The real joy of programming in Julia is only really accessible after :

  • Finding and solving super-complex bugs based on uninitialised pointers in C

  • Discovering purify, valgrind and all the other tools that allow you to survive in undeveloped code produced by hostile third parties.

  • Having sweated over C++ code produced by beginners who more or less understood that it was classy to put inheritance everywhere with a maximum of side effects and discovered a grandiose variant of spaghetti code: melted lasagne code.

  • Having to endure for many years two (or three?) language code with Python/C++ interfaces whose size threatened to exceed that of the code itself.

  • Having to rework F77 code with and without implicit none into a 10,000-line file and two functions.

Nearing the end of the course, you discover Haskell: it’s so beautiful that you decide on your own that the code you could produce with it would only be an insult to the language, and you envisage a new job for the first time: manager.

Only then will the true joy of programming in Julia become apparent. No, you won’t think that all this suffering was pointless. On the contrary, they were all necessary to understand the purity of this unexpected paradise.

From the top of your new Eden you see a youngster coming to drink your water… horror, he’ll never be able to face the harshness of the real world again if, by some misfortune, his employers force him back down to the harsh reality of the well-established languages of the industrial world.


Thank you all for this great thread. It’s rich in ideas and point of views.

If I may add something, education is not a one-side-fits-all. So, what a good first language to learn is depends on many different factors.

  1. How the student is.
  2. What education background they come from.
  3. What they are trying to learn.

Or, to be more cheeky, not everyone is a freshman computer scientist trying to become a software engineer. :smile_cat:

I did teach Julia to university students with no programming background. They were in a path toward becoming “applied data scientists”. And they needed to learn how to wrangle data. They also needed to learn that most concepts and techniques in data wrangling are not language-specific (i.e., no, data frames are not just R things, and no, web scraping is not just a Python thing). Julia was a great experience (and I started teaching this course in 2018, so there was still a bit of instability in the language).

One great thing for them was the broadcasting and the fact that loops are not slow. That allowed for a “we build a function for an example input, and then scale to many inputs” kind of workflow.

In general, for students coming from a strongly mathematical (largely written) background, Julia is very pleasant as it lowers the jump from “how I would think and write this in mathematics” to “how I would write it in Julia”. They don’t usually care so much about “the machine” nor whether Julia is dynamic, OO, functional, compiled, … Maybe some will get curious, but others just want to code to prove their ideas. They are not becoming software engineers, they are becoming mathematicians/statisticians/biologists/psychologists/… who code (sometimes very well, and very complex things). And you don’t want to enter a classroom of biologists and try to teach them C.

PS I don’t teach that course anymore but I’ll be teaching one on Data Engineering next semester, where I will try to include as much Julia as possible, send me ideas :bulb: if you got any or you are keen to be a guest.

PPS there are biologists who are C wizard and witches, and would code you up a storm, no disrespect meant. It’s only a question of priorities.


My view on this is that Julia’s base API and standard library is opinionated on being “right” and “efficient” over being “easy”. There are also some inconsistencies due to evolution of the language and community design. I could enumerate them but many others have already done so and doing so will distract from the actionable steps.

If we would like Julia to be easy for new programmers, I suggest a Basic API package. The Basic API should value simplicity over all else, with ample documentation about why it may not be the most correct or efficient way of doing things in auxiliary help sections.

Here are some thoughts about what what that might entail.

  • Minimal direct use of type parameters.
  • Minimal use of curly braces.
  • Minimal use of macros.
  • Minimal use of in-place functions or any modifications of arguments.
  • A simple array constructor with no undef. E.g. emphasize zeros.
  • Ample use of keyword arguments when there is any ambiguity.
  • Use the minimum number of types.
  • Avoid use of generators and other “lazy” types in favor of their eager equivalents. e.g. collect everything.
  • Use if else rather than try-catch when possible. This may mean returning nothing and introducing type stability.
  • Use for loops rather than broadcasting or other reductions or folds.

This effectively would look like a distinct language but it would still technically be Julia, and that’s a place to start. Some will argue this is not Julian, not idiosyncratic Julia. That’s fine because this sublangauge has vastly different objectives. In particular, the main objective is to introduce basic programming to someone with no programming background.

What’s neat is that I think this is quite possible for us to create a BasicJulia dialect.


That looks pretty much what I do most of the time… maybe except for the broadcasting.


I think this vastly underestimates new programmers to their detriment. I do agree broadly that people should be eased into features, but a separate package that omits too many features also omits basic concepts people can easily learn and frustrates them with limitations. I am confident that people would hate to read the auxiliary help sections after all their effort going through what is effectively a tutorial, and realize that they didn’t really learn idiomatic Julia because the package authors didn’t think they could. Meanwhile their peers starting Python got to mutate a list on day 1.

Instead, I think those guidelines should be repurposed toward designing a beginner’s tutorial with many code examples, and those guidelines are progressively dropped as new concepts are introduced. It’s a matter of whittling down examples concept by concept, while keeping the code idiomatic and practical. People should leave the tutorial able to explore code and navigate packages on their own, not get blindsided by idiomatic Julia.

  • People can definitely understand argument mutation and initializing undef arrays, it’s not hard.
  • Type parameters are something you want people to grok early on, especially if they’re coming from Python where element types are shoved in arguments and attributes. You don’t want people ad-libbing type parameters in weird ways.
  • I think macros should be introduced early on, but very quickly and not how to write useful ones. It’s useful to explain that expressions are parsed and evaluated one by one, that macros transform an expression during parsing, and that macros should not be designed to replace existing structured expressions and higher order functions. Then it’s fairly safe to let people use macros. I see many users thinking @dothis(x) is just another function call, sometimes despite having seen others call @dothis a “macro.”

As for the overall question, it depends on first language for what purpose. Just any programming? Sure, Julia will get people thinking about types, functions, and structured programming as much as any other language. But for microcontroller enthusiasts, no. There are also many distinct paradigms, so if someone wanted to lean into object-oriented languages with statically typed variables and pointers, then definitely not.


That sounds like the first great idea! :smiley:

Still, I would question if that wouldn’t make more sense for a library, that is entirely dedicated to this purpose of education, and not touting it as some kind of productive library.

I also discourage everyone from writing stuff like, “why this may not be the most efficient way” and something of that sorts. The last thing I want to know, when learning new things, is that I am actually doing it wrong, or somehow not good enough.

Just imagine you are teaching your kid bicycling, and as they are doing that, you tell them,
“The grown-ups use no support wheels, and until you don’t use them, you are not really bicycling.”

Just tell them how to do it without support wheels in a later training session.

I absolutely agree with you here :smiley:

I think immutability, and immutable data structures as such, are much more sensible to teach at first.

We are talking about Julia as first language, so they dont come with baggage from Python.

Could we say, that this simply comes down to teaching them how to use macros, and not how to write them?

1 Like

Teach beginners about macros, that is, they should be aware that macros are not function calls and each one has independent syntax, but teach them not to write macros. IMO macros are hugely overused and writing a macro should require a license, so to speak. Pehaps it would be beneficial to disable automerge of general registry PRs for packages which define public macros?

1 Like

I think it’s mostly a pedagogical issue.

If you need to prevent them from committing stuff that uses macros, you are also admitting that we failed to communicate, why we don’t use them for their use case.

That only covers our miscommunication.

It reminds me of Elm.

People there are prominently exposed to absent type classes, and some people literally wrote violent threats about that decision. Evan, the language designer used them in the language itself, but deemed them to be too powerful, to be used as part of the language.

Clear split between usage internally and externally. People didn’t like that. I think it’s a smart decision.

You don’t need type classes, to implement frontend web apps. :man_shrugging:t3:
Elm did choose to not provide those complex features to the people, since they knew, it would abuse them.

F# and other languages deliberately did the same, to keep the language simpler, for the purpose of simpler codebases. While they are advanced languages, are capable of implementing macros and first class modules, they deliberately stay away from them, to prevent abuse.

Nim has superb macro capabilities, as it is also homoiconic at its heart, and people are abusing macros as well. And macros are advertised on the front page, and touted as one of the key features.

So we can choose, supposedly, between abuse of power and no power at all.
I simply don’t think that is a good split. I think we can do better. :wink:

The documentation makes a very good job, to warn about macros right now.

I think it’s sufficient, to tell people, that using macros is a beginner topic, and actually implementing them is a topic for people who are on the opposite side of experience. :slightly_smiling_face:

So, I think splitting it into two - using macros and writing them - helps to avoid the dichotomy of overusing them and presenting them as a solution.

It would let people feel involved, and as a part of the family.


The more I think of it, I think it may be beneficial to ping someone, and set a tag.
When someone commits stuff that contains a macro, simply set it to macro and let people inspect it. I would also create a message, that reads like “are you sure… these are the implications”

But outright preventing them from committing, is too steep, imho.
It feels too strict.