Hacker News new | ask | show | jobs
by DNF2 1828 days ago
But this is what most languages do, except they have _singular_ dispatch. Every OOP language has different behaviour for different input types, except it only works for the _first_ input argument. Julia simply extends this to every argument.

How would you feel about having to write `sqrt_int32(x)`, `sqrt_int64(x)`, `sqrt_float64(x)`, `sqrt_rational_complex_float16(x)`, etc, etc, etc, etc, instead of just `sqrt`, and let dispatch or overloading take care of the different implementations?

1 comments

> Every OOP language has different behaviour for different input types

Yeah. And I find OOP horrific.

> How would you feel about having to write `sqrt_int32(x)`, `sqrt_int64(x)`, `sqrt_float64(x)`,

What kind of savage wants the square root of an integer? I'd prefer if the language only had a single number type (maybe configurable at once by an external option) and a single sqrt function.

But if you talk about the general problem of naming functions differently according to their types, I feel that it's perfectly OK. A tiny price that I'm eager to pay for the large benefit of being able to identify which function is called just by looking at its name (and not at the---possibly yet undetermined---types of its arguments).

But this is precisely what Julia allows you to do.

Your function may be written for numeric, and you use your favorite kind exclusively.

Now person B from this thread comes along, using both ints and floats. Well guess what, your package still works seamlessly. And where it doesn't, it must be due to a particularity that you yourself don't care about. In any case, the function can then be extended without namespace issues. In other languages, one would have to rewrite your package since you are using an obscure numeric type which others don't agree with.

Consider for example how people have used solvers for differential equations with entirely new datatypes, simply because the compatibility comes for free.

I think it's really neat!

I think it's great!

> I'd prefer if the language only had a single number type (maybe configurable at once by an external option) and a single sqrt function.

If you meant a numeric single type class, like haskell's Num, I think it's a great option. If you mean a single numeric type, like javascript, it unfortunately leads to a bunch of issues. Integers and floats really are both necessary very frequently. For example floats to represent something like speed, and ints to represent your bank balance. And you need different sizes of them (like float32 vs float64) are still necessary in a ton of applications, so you'll need them eventually if you want the language/numerics library to be truly general purpose.

It's also a huge convenience to be able to apply e.g. `+` to arrays as well as numbers and other polymorphism niceties.

> What kind of savage wants the square root of an integer?

It comes up moderately frequently (e.g., in prime sieves). It's usually defined as the largest integer X whose square X^2 is no greater than N. Search any sufficiently large codebase (postgres or something) and you'll probably find one or more functions called something like "isqrt".

My favorite implementation just takes Newton's method and blindly applies it to integers. It happens to converge for at least one starting value.

good point! but notice that this is an entirely different function than flotaing-point sqrt; and it has, appropriately, a different name.
The integer square root is mild a generalization of the floating point square root (in the sense that if you swap ints for floats you get the ordinary sqrt back out). With that in mind, do you think that the different name is chosen because it's a fundamentally different operation or just because of limitations in the dispatch mechanisms of common languages?
it would be very confusing to have both functions go by the same name. Very often you want the floating-point valued square root of an integer. Having the two functions with different names is much clearer, and better than forcing a conversion just to dispatch another function that performs a different computation.
> I'd prefer if the language only had a single number type

> But if you talk about the general problem of naming functions differently according to their types, I feel that it's perfectly OK.

You and I have nothing in common in this entire world.

Why on earth would you even want to touch Julia with 12 lightyear stick? The whole point of Julia is diametrically opposite to your preferences.

Being opposed to multiple dispatch, polymorphism and generic programming, while 'liking' Julia, is similar to loving bycicles, but abhorring wheels.

But I really love Julia! I was seduced by the idea of "like octave, but with fast loops", which is exactly what I need and the interpreter pretty much lives to that ambition. Also I love the examples with single-letter greek variables, the "f.(x)" notation, everything. And the fact that it feels like a well thought out language for numerical computing, cleaner and more beautiful than matlab/octave, and not an ugly kludge like numpy.

The multiple dispatch and oo features are some unfortunate warts, but I can live with those. Following your analogy, I love bikes and Julia is an electrically assisted bike. Sure, I would prefer if it was lighter and without the stupid motor, but it's still a bike. Not like numpy which is a horse carriage.

> You and I have nothing in common in this entire world.

for one, I 100% agree with your views on variable naming elsewhere on this thread ;)

> "like octave, but with fast loops"

But the performance relies on the aggressive specialization which depends on multiple dispatch. And the adaptation to numerical computing, the cleanness and beauty is all about multiple dispatch.

To stay with the bike analogy, multiple dispatch is definitely the wheels, not the motor.

> for one, I 100% agree with your views on variable naming elsewhere on this thread ;)

Waaah! (pulls hair.) And yet, so far apart on the function naming ;)

But seriously, though. Without the incredible polymorphism and genericity, there's really nothing at all left of Julia. Multiple dispatch isn't a feature bolted onto Julia. It is the core philosophy, and the central organizing principle.

> But the performance relies on the aggressive specialization which depends on multiple dispatch.

This is not a necessity, but an implementation choice. "Specialization" is an unnecessary step when everything is explicit from the beginning. I'm not talking on philosophical grounds, but thinking on concrete examples of jit systems which are really fast but have nothing to do with multiple dispatch (for example luajit).

> Without the incredible polymorphism and genericity, there's really nothing at all left of Julia.

If "matlab with fast loops" is "nothing" to you, sure. As a user of Julia, this is the killer feature for me. The rest I see as unnecessary complexity and mumbo-jumbo. But there's nothing wrong that each user has different favorite parts of the language!

Actually, come to think of it, Matlab is now fully jit-compiled. As long as you stick with double precision floats, there is already a "Matlab with fast loops": it's called Matlab!

Just stay away from classes and other complex data structures, which you don't like anyway, and performance is very good indeed.

Cannot reply to deeply nested posts, so I put the answer up here:

> This is not a necessity, but an implementation choice.

The performance of Julia relies on algorithmic specialization, and since you do not know what input types your code will receive, you cannot take advantage of clever specializations. I understand that you reject the concept of allowing user types that can be used by generic functions, but then you throw all the performance out the window. I want to do fast linear algebra, but your library says "no special static arrays!", "no special handling of diagonal matrices", and in general no exploitation of special structure in user types.

I want to calculate fast derivatives, but your library doesn't accept dual number types.

Your code will never be fast if it's only fast Float64, because it's when my special type elides all computation that the real speedups arrive.

> "Specialization" is an unnecessary step when everything is explicit from the beginning.

But you cannot know what it should be explicit about. I give your `sum` function a special Range vector, or a BitVector, or a OneHot vector. What should it do? It has to fall back to the same thing it does with all arrays: add-add-add-add-add. What is the norm of my UnitVector type? Your library has to ploddingly square, sum and sqrt. In the meantime, multiple dispatch just replaces the call with the number 1.0.

> If "matlab with fast loops" is "nothing" to you, sure.

As a daily user of Matlab for 25 years, several tens of thousands of hours of grudging use, I assure you it would be less than nothing. Matlab is a tragic, horrible mess of a language, and it's not even that slow! I rue every hour I've spent on it. If Julia were slow, and Matlab faster, I would still prefer Julia.

Also, Matlab has OOP and sigular dispatch.

> But there's nothing wrong that each user has different favorite parts of the language!

Well, as I am trying to say, multiple dispatch isn't a part of the language. It is the language. Everything revolves around that concept.