News for hackers. Stuff that matters.
Re:Calculus with Julia by RivieraKid on Saturday May 18, 2024 @06:41PM (#40402695)
I quite like and use Julia but wish there was a language mixing the best aspects of Julia and Swift (which I think can be done without many compromises, i.e. it would be a better language overall).

Some things I don't like about Julia:

- array.mean().round(digits=2) is more readable than round(mean(array), digits=2)

- Poor support for OOP (no, pure FP is not the optimal programming approach).

Re:Calculus with Julia by staplung on Saturday May 18, 2024 @07:04PM (#40402805)
Well, Julia also has a pipeline operator built in so:

  array |> mean |> x->round(x; digits=2)
will do what you want and is arguably more readable than dot notation.

Not supporting OOP is very much intentional. It has structs and multiple dispatch (which has proven to be insanely useful in Julia's domain of scientific computing) so about the only thing you lose is the namespacing that dot syntax facilitates.

Re:Calculus with Julia by brabel on Sunday May 19, 2024 @07:06AM (#40406031)
That's not more readable, you're just switching a few characters.

Any language that has Uniform Function Call Syntax (UFCS) [1] lets you replace wrapped function calls with linear calls like that, it's clearly easier to read, and much easier to write, specially when you consider programmers' tooling (in case it's not obvious why: you can type the name of a symbol and a '.' and the IDE shows you the available functions... this works also for free functions that take the symbol's type as the first argument as well.... that could work for the pipe operator as well, of course, that's why I said that the two things are basically equivalent, just with slightly different notation).

[1] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

Re:Calculus with Julia by patagurbon on Saturday May 18, 2024 @06:49PM (#40402731)
You can overload your own types to get a lot of those things (poor support for OOP is harder but you can sort of emulate it with traits). Overloading `getproperty` for the former case.

Of course it's not built in, which I understand is annoying if that's your preferred coding style. I personally am sad that really good traits aren't encoded in the language.

Re:Calculus with Julia by abisen on Saturday May 18, 2024 @06:50PM (#40402739)
If I am not using named arguments I find myself using the pipe operator a lot. I also find it more readable.

array |> mean |> round

For scenarios with named arguments there is a little not so cleaner workaround

array |> mean |> x->round(x, digits=2)

Re:Calculus with Julia by andyferris on Saturday May 18, 2024 @07:42PM (#40402998)
array |> mean |> round(; digits=2) should also work and is a bit more concise.
Re:Calculus with Julia by SatvikBeri on Saturday May 18, 2024 @11:08PM (#40403917)
This doesn't work, at least for me on 1.10. `round(; digits=2)` would have to produce a function. But Julia doesn't have automatic currying, so that only happens if someone has implemented a special-case version (e.g. (==)(3) returns a partial function that tests for equality with 3.)
Re:Calculus with Julia by abdullahkhalids on Saturday May 18, 2024 @09:52PM (#40403541)
> round(mean(array), digits=2)

is how mathematicians have thought for hundreds of years now. They do so in this way, because it's indeed easier to parse, and philosophically it correctly represents what is happening mathematically.

> array.mean().round(digits=2)

is how a subset of software engineers have thought about computation in the last couple of decades.

Technology should whenever possible adopt already existing conventions, because technology is created to serve the user, and not vice versa.

Re:Calculus with Julia by adastra22 on Saturday May 18, 2024 @10:06PM (#40403602)
> is how mathematicians have thought for hundreds of years now.

"Because tradition" is not a good argument. We can and should strive for better.

The modern OOP-derived style of `array.mean().round(digits=2)` is just as exact in its specification, and arguably more semantically precise as well as it organizes the meaningful bits to be together.

Also I think you don't account for how much mathematical notation has changed over the years. The `round(mean(array), digits=2)` structure is relatively recent, early 20th century I believe, and the result of active reforms.

Re:Calculus with Julia by abdullahkhalids on Sunday May 19, 2024 @12:23AM (#40404266)
> mathematical notation has changed over the years.

I agree. Math notation has changed in response to problems mathematicians have faced, and as their thinking have evolved. It should not change because tool builders for mathematicians - when the tool builders in most cases are not even professional mathematicians - decide some other notation is better.

> array.mean().round(digits=2)

might be good (it is not) when you are operating on one object. As soon as you have a binary operation (say multiplication), this notation completely breaks down. Because the operation is often symmetric, or "near" symmetric, meaning it is not so different as to write something as ridiculous as x.product(y).

But more importantly, (common/dominant) mathematics is functional in nature. It's decidedly not object oriented. Given a matrix, M, doing something like M.eigenvalues() is vomit-inducing because eigenvalues is not a property of a matrix M. For matrices, its a map from a set of linear transformations (of which M is merely one item) onto a set of numbers. It is its own thing, separate from M.

Re:Calculus with Julia by bee_rider on Sunday May 19, 2024 @02:01AM (#40404570)
In programming it is typical to have an “eig” function, or something of the sort, which returns the eigenvalues of a matrix. eig(M) seems no less vomit inducing than M.eigenvaues(). Usually when mathematicians want eigenvalues they write something like “Given a matrix M with eigenvalues \lambda” and the eigenvalues just show up.
Re:Calculus with Julia by samatman on Sunday May 19, 2024 @09:49AM (#40406955)
In Julia:

    M = [1 2 3; 4 5 6; 7 8 9]
    λ = eigvals(M)
Which is much the same.
Re:Calculus with Julia by bee_rider on Sunday May 19, 2024 @11:37AM (#40407616)
Sure, my point is that even the math-y programming languages and libraries don’t map very well to how mathematicians seem to describe eigenvalues.

Personally I think of them as a characteristic of the matrix (but I just write numerical software, I’m not a mathematician) and implement them as the result of a process. So I don’t really see any reason to favor either syntax or call one more mathematical.

Re:Calculus with Julia by adastra22 on Sunday May 19, 2024 @12:30AM (#40404288)
Now you're gatekeeping on who is a real mathematician?

I don't think this subthread is going to be productive and I'm bowing out.

Re:Calculus with Julia by nightlyherb on Sunday May 19, 2024 @01:51AM (#40404533)
I'm not the GP, but I'm sorry you felt gatekeeped. I don't think GP conveyed "real mathematicians should do FP", but rather something else, so I'll try my best to share what I understood from that comment. Hope this makes you feel better.

Even though the notation changed over the years, the paradigm of "numbers as immutable entities and pure functions" has been the dominant way that math is presented, compared to something like "encapsulated objects that interact with each other via sending messages".

I don't think this has to be this way, and I do think that "real math" can also be laid out assuming principles of OOP. However, I do suspect it's the way it is because the laws of nature are unchanging, in contrast to the logic of a business application.

Because Julia is a tool with the target audience of mathematicians and scientists, I think it's a sensible decision to embrace the usual way of thinking, as opposed to presenting a relatively different way of thinking which steepens the learning curve. Not because data and functions are fundamentally better than OOP, but because it's more pragmatic for the target audience.

Re:Calculus with Julia by adastra22 on Sunday May 19, 2024 @03:06AM (#40404852)
I understood the other poster correctly. This view of mathematics is as limiting and ignorant as the other poster’s.

The entire field of theoretical computer science, to which functional programming and type theory is closely tied, is a branch of mathematics. The Church-Turing thesis which gives both to our field equates the two at a very fundamental level. Questions about type theory, programming language design, and programmer ergonomics are fundamentally about math and applied math.

Maybe you and the other poster have in mind specific fields of math, but then you need to make claims for why those fields are sufficiently different as to be exempt from applicability of any of the advances in notation observed in other fields.

Your implicit assumption that you can divide computer science into a different bucket from “real math” is incorrect, and gatekeeping.

As I said though, I don’t think this is a profitable debate to have here on HN.

Re:Calculus with Julia by nightlyherb on Sunday May 19, 2024 @03:48AM (#40405100)
Okay, I see what you mean.

> Maybe you and the other poster have in mind specific fields of math,

Yes, because this is about Julia, I assumed we are talking about the specific fields of math that happen to be commonly used in mathematical and scientific computing, such as the ones learned in university math and science courses.

> Your implicit assumption that you can divide computer science into a different bucket from “real math” is incorrect, and gatekeeping.

It is regretful that we had a miscommunication. I agree with you that computer science belongs into the same bucket as "real math". The thing is, in the context of Julia it is not easy to read "math" as "math, but not only the domains that Julia is concerned in, but really all fields of math, including theoretical computer science". At least thanks to your comment, I see what you mean more clearly, and I think it'll help some other potential readers as well.

> but then you need to make claims for why those fields are sufficiently different as to be exempt from applicability of any of the advances in notation observed in other fields.

I'm curious to know specifically about the specific advances of "notation observed in other fields". By this you mean dot notation for method application? I'm unsure if `a.method(b).anotherMethod(c)` is any different from `a |> method(b) |> anotherMethod(c)` (Edit: or `(anotherMethod(c) . method(b))(a)`) notation-wise.

Re:Calculus with Julia by nightlyherb on Sunday May 19, 2024 @05:14AM (#40405499)
I'd like to add another point worth mentioning. When I read the other poster's post, I was thinking about the semantics of OOP, specifically encapsulated objects and messages. I may have misinterpreted the other poster, but I hope it at least makes my other messages a bit clearer. (I think it's a little unwieldy to use Matrices that encapsulate its state for Linear Algebra, for example.)
Re:Calculus with Julia by FabHK on Saturday May 18, 2024 @11:07PM (#40403910)
I used to miss "OOP" in Julia. The funny thing about the dot notation is that it makes the limitations of single dispatch seem natural. Once you get used to multiple dispatch and its benefits, the dot notation seems limiting.

`x.plus(y)` dispatches based on (runtime) type of x (polymorphism) (single dispatch), and might call different functions based on the (compile time) type of y (function overloading)

In Julia, it would be `plus(x, y)`, and it can dispatch based on the runtime type of both x and y (or determine the correct method to call at compile time already, if the types of x and y can be determined then).

Re:Calculus with Julia by adastra22 on Sunday May 19, 2024 @03:09AM (#40404878)
Virtual method dispatch isn’t always a good thing though. It’s a tradeoff and typically you really want one or the other. C++ makes both available for that reason, although C++’s syntax is horrible.
Re:Calculus with Julia by jakobnissen on Sunday May 19, 2024 @04:26AM (#40405290)
It's multiple dispatch though, not virtual dispatch. If I understand correctly, virtual dispatch means the method is picked at runtime. In Julia, the compiler is able to pick the correct method at compile time, even when dispatching on all arguments of the function.
Re:Calculus with Julia by samatman on Sunday May 19, 2024 @09:53AM (#40406982)
This is correct, but it's important to realize that compile time continues during runtime.

Julia's execution model is quite distinctive, and it does take a thorough understanding of how it plays out to get native-code speeds out of it.

Re:Calculus with Julia by nightlyherb on Sunday May 19, 2024 @01:07AM (#40404408)
As a person who respects many programming paradigms including OOP and FP, I beg to disagree. Specifically, I'm assuming you're talking about OOP the paradigm, not only the dot notation, for which the pipe operator is a viable alternative.

> The modern OOP-derived style of `array.mean().round(digits=2)` is just as exact in its specification, and arguably more semantically precise as well as it organizes the meaningful bits to be together.

I would have agreed with you if I were developing business applications. However, for the domain of math and science, every piece of material that I have seen assumes the paradigm of numbers as immutable entities and functions, not the paradigm of mutable encapsulated objects and interacting messages. To a mathematician or scientist the semantics of a `Vector` (as data) and a `mean` function that takes the `Vector` as input should be more natural than a black-box `Vector` object that can receive a `mean` method.

Re:Calculus with Julia by RivieraKid on Monday May 20, 2024 @10:02AM (#40415567)
To me, the second is more readable, more pleasant to work with especially if you're using an IDE. And ultimately, it leads to higher productivity.

It may be philosophically correct per some definition of philosophically correct but this is not what I care about.

Re:Calculus with Julia by DNF2 on Monday May 20, 2024 @10:21AM (#40415751)
In some cases, applying a limited set of basic operations might make up a significant part of development time, but in my experience most of the time is spent designing algorithms, parsing function input and managing the flow of vectorized expressions across function boundaries. And that is generally more efficient in the context of multiple dispatch with efficient loops.

For example, writing a function that works on scalars, then mapping or broadcasting it over array input is very good for productivity (and is efficient in Julia). On the other hand, designing an inherently array-based algorithm is often a headache that one must contend with for the sake of performance in numpy.

So, if you design somewhat complex or novel algorithms, I don't think object-dot notation, or the lack thereof, has a significant impact on productivity.

Re:Calculus with Julia by ssivark on Saturday May 18, 2024 @11:33PM (#40404046)
> Poor support for OOP (no, pure FP is not the optimal programming approach).

Julia is not really a pure functional programming language, though it does support that style if one desires.

It's actually a "multiple dispatch" language... thinking of OOP as single dispatch, Julia is conceptually OOP on steroids -- but to benefit from the full expressiveness, the programming style looks different from the typical OOP syntax/patterns one is used to.

Re:Calculus with Julia by waveBidder on Sunday May 19, 2024 @01:22AM (#40404458)
having spent my PhD writing in Julia, coming back to object oriented programming felt like programming with a hand tied to my back. many operations just make more sense dispatching on multiple arguments rather than just one, and. cramming methods into a class felt unnatural
Re:Calculus with Julia by neonsunset on Sunday May 19, 2024 @06:32AM (#40405868)
Re:Calculus with Julia by pjmlp on Tuesday May 21, 2024 @04:24AM (#40425539)
Interesting remark about poor OOP support, when multi-methods and their interaction with protocols are two cool CLOS features yet to be fully embraced mainstream.