Julia for prototyping, compared to MATLAB?

Here are some points, off the top of my head. Several of them overlap with points raised by other posters:

  • Functions need own file in Matlab and all files in path intrude in namespace

Whenever you want to define a function, you can’t do it from the command line, or inside a script (except with some major limitations)

  • Dispatch vs input parsing

Input parsing in Matlab is a nightmare. You have the inputParser class now, but it seems really heavy and awkward.

  • Default values and keyword arguments

This is related to the above. You can `fake’ keyword arguments using two consecutive inputs, one string for the keyword and one for the value. It’s an awful kludge.

  • Everything in Matlab is a matrix (or a higher dimensional array)

You can’t have scalars, so you always have to consider the ramifications of the fact that your value is a container with a shape and linear algebra-like behaviour. Often you want your code to behave one way if it’s a `scalar’ and another if it’s a vector and a third if it’s a matrix. But it’s always a matrix, and it requires a lot of awkward tests and planning. (Is a single number a scalar, is it a vector or is it a matrix?)

  • Possible to mutate objects (no copy on assignment)

When you assign to a variable, the object you assign is copied. So you cannot pass an array into a function to mutate it (Matlab can only somtimes mutate as an optimization if certain cases). Mutation is supported for user classes that inherit from the handle class.

  • Julia can define functions like +() and *()

It’s great!

  • Direct access to objects with indexing for example

a[i][j] or foo(x)[1] etc are impossible in Matlab, so you must create intermediate variables.

  • Better handling of variable inputs and outputs with splat and slurp

varargin and varargout in Matlab is an annoying mess to work with.

  • Much better iterators

Matlab doesn’t have proper iterators, so you will normally have to do for n = 1:length(x). You can in principle write for val in x, but it only works for 1xN vectors, not Nx1. For a matrix each iteration will actually return a column of x.

  • 1d vectors avoid orientation confusion

Column major language, but almost all internal functions return row vectors. Also, iteration only works for row vectors, as mentioned. Proper flat 1D vectors are amazing.

  • Map and broadcast vs cellfun, arrayfun, structfun, bsxfun

Vectorizing code is the major coding style in Matlab, but it’s so inconvenient. You have no general map function, let alone the awsome broadcasting (you have a really pale type of broadcasting that works for +-*/). Instead you have different and awkward functions, cellfun, arrayfun and structfun for different types of collections.

  • foo is a function call

You don’t have to use parens for a function call, so you cannot tell if foo is a variable or a function call. Passing functions around requires using @ to create a ``function handle’'.

  • Creating empty containers of specific class is awkward in matlab

Due to everything being a matrix it is actually really hard to create empty arrays of objects. I struggled to implement this for some classes recently. You can do it, but it’s messy, verbose and hard to understand.

  • Poor support for hash tables/dictionary

There’s containers.Map which noone uses.

  • Generators and comprehensions

These are incredible, and there’s nothing like it in Matlab.

  • Explicit multithreading

Nope.

  • char arrays and strings in matlab

This is a big mess. Previously strings were char arrays, and they are still what is mostly used throughout the language. Now they have more proper strings, but they are barely used, and also, of course a string is always a [1x1] string array. I can’t really go into this, but it is awkward.

  • Operations that only accept small number of input types.

This is a common problem in most programming languages, except Julia, as far as I can tell. ``Sorry, this function only accepts double floats.‘’

16 Likes

As @balinus wrote, the prototyping/exploration phase can often be badly slowed down by the computing time required by the numerical experiments to complete. I have witnessed too many times laptops moaning in (relative) silence while they were bravely trying to complete probabilistic computations for hours/days/nights (usually on a single thread).

Such quantity of wasted computing (and electrical) power drives me several time to write C++ kernels for MATLAB users. I may have felt proud and marginally useful doing so :wink:

With Julia, the very same mathematicians/scientists can reach high performances on their own. So, probabilists’s laptops of the world say (in their chest) thank you Julia !

2 Likes

Unless they are subfunctions to the main function in the file, in which case you instead cannot access them outside of the main function, making unit testing of those subfunctions a major pain. (Actually I found a way to retrieve subfunction pointers, but it’s most horrible hack I’ve ever done.)

Disclaimer, I haven’t followed Matlab developments since ~2014 so maybe there’s a solution to this problem now.

2 Likes

Not that difficult to workaround

function  varargout = mylib(fun_name,varargin)
	if (nargout)
		[varargout{1:nargout}] = feval(fun_name, varargin{:});
	else
		feval(fun_name, varargin{:});
	end

function fun1
function fun2
...

and call it like

out = mylib('fun1', args);

That appears to be an extraordinarily unpleasant way of defining functions.

2 Likes

It was not meant to be pleasant but to make possible a case that is otherwise not in Matlab

I understand, it’s a clever hack :slightly_smiling_face: It’s a nice example of what people work out to workaround shortcomings of the language. The fact that you worked out such a solution emphasises how severely limited the matlab language is.

1 Like

The preferred way to handle namespacing in MATLAB is to put the functions you want (all as separate files) in a folder that starts with ‘+’. So you would have fun1.m and fun2.m in a +mylib folder then you can call mylib.fun1(...). To be honest, I don’t find it as awful as everyone else seems to. I mean, it is a little annoying that you have to have all of your externally callable functions in separate files, but in the large space of my MATLAB gripes, this one takes up a pretty small corner.

2 Likes

I think it’s pretty annoying for interactive work, when I just want to define a throw-away function. The overhead of coming up with a name and a location to store the file, and make it available, but avoid all the other old throw-away functions you made, is to me similar to the annoyance of having to come up with a username/password combination for throw-away accounts (that is, the overhead is pretty big.)

3 Likes

Thanks for bringing this thread back alive—I am still learning (and struggling) a lot, but the slack channel really helps with random small questions that I need to ask on a daily basis. My feelings so far: I love the syntax and the community, and when Julia works I am very happy. But often I am frustrated by what I feel “non-programming” issues (which isn’t true, but I am used to MATLAB’s “works out of the box” paradigm), like something breaking, no knowing how to get something to work, developing packages, managing paths, etc. For example, right now I got my analysis script running and formatted nicely but I can’t get weave.jl to produce a report I need to submit (some issue with plotly backend plots not being generated).

I recently bought the book Hands-on Design Patterns and Best Practices with Julia by @tk3369 to get a feel for, as you said “modern software engineering and workflow”. It is not specifically for MATLAB users, and is not a beginner book, but from what I read from the preface seems to cover general principles that are applicable in all domains. I’ve only read it for a day, so can’t vouch for it yet but the general tone of the book is very gentle and encouraging.

I’d love to hear from @tk3369 about what he feels about people coming from propriety languages such as MATLAB and how we can make the journey to effectively using Julia as smooth as possible.

5 Likes

Hey @ElectronicTeaCup, thanks for the tag.

Unfortunately, I am not a Matlab user and I can’t quite feel the pain that everyone else went through. On the other hand, I am always amazed that many people in this community can write very good code even without any computer science background.

I cannot say whether it works for everyone but I can definitely share how I learned Julia:

  1. Get on the REPL often and do small experiments
  2. Learn to use development/productivity tools e.g. VSCode, Revise, etc.
  3. Build a package and register it. It can be a small thing and that’s ok.
  4. Write unit tests and enable CI checks e.g. Travis, codecov, etc.
  5. Read other people’s code e.g. there are some real good ones from Invenia.
  6. Ask a lot of questions. There are no dumb questions. Sometimes your question leads to very interesting discussions.
  7. Write a blog post about what I learned.
  8. Try to help others out in public channels/forums (and be surprised when someone else comes up with a better answer.)
  9. Have some fun playing online contests e.g. advent of code, CTF’s.
  10. Try to follow conversations on Slack, Discourse, etc. for topics that I don’t understand or familiar with.

Let me tell you my favorite story. While reading some string manipulation code in Base during my 2nd month of learning Julia, I came across a bug in rstrip and I reported it here. It led to a constructive motivational reply for making a PR. The thread went on about what the correct fix should be. Eventually, I got excited and submitted a two-line fix. It feels good to contribute to Base :slight_smile: If I can do it, you can do it, too.

Hope it helps.

Tom

12 Likes