Live data from Hacker News

JuliaLang: The Ingredients for a Composable Programming Language

white.ucc.asn.au

91–100 of 228 posts

Re: JuliaLang: The Ingredients for a Composable Programming Language

#91

Composable? Julia and composable?!? They decided on sequence range [1...N], instead of [0...N) like Python. Try to compose that.

Depends on what you work on. When doing more computer science like stuff, such as computing memory offsets etc, then 0-based indexing is practical. But for numerical work 1-based indexing is usually easier to work with. Mathematical texts are already using 1-based indexing and hence that is what people are used to when thinking about math. I work with both and I never found this a big problem. This is on par with com…

> Mathematical texts are already using 1-based indexing

For matrices and vectors, usually. For series and sequences 0-based comes up quite often too.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#92

Earlier quoted context omitted.

What does this have to do with garbage collection? If your concern is about latency in real time systems, Garbage collection isn't the problem, heap allocating memory is. Julia makes it easy to never allocate anything on the heap (unlike most garbage collected langauges). Check out this talk this discusses this in detail in the context of robotics: https://www.youtube.com/watch?v=dmWQtI3DFFo

I think the above poster is referring to languages like Go/Java/C#/Nim/whatever. Like Julia, these languages have a significant runtime. Unlike Julia, their apps can be compiled AOT into standalone executables.

My point exactly! Thanks for clarifying.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#94
post #77

Earlier quoted context omitted.

Programming languages from 2000 remain, though. C, C++, Java, JS, Python, etc. Even Fortran, Cobol and Lisp remain in use. There’s been attempts since the 80s to popularize visual and and higher level approaches to programming, but the traditional languages still dominate. And the newer ones like Go, Elixir and Julia are like the traditional C, Lisp and Fortrans.

More than this, C is from the 70s, and C++ is from the 80s. This is 50 years from now for C. So I'd say python is likely to be still here 20 years from now, given how popular it is.

Python will still be around, but how popular it'll be is an open question. For example, Pascal or Perl were huge in their prime, and while they continue to stick around, the torch has been passed on.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#96
post #27
post #25

Earlier quoted context omitted.

People write large-scale systems in dynamically-typed languages all the time. Multiple dispatch and macros make clean scaling easier than it would be in most other dynamic languages. Its competitors in numerical performance are C/C++ and Fortran, which are both minefields (C much more so). Julia is definitely safer in practice than these kind of languages with weak, unsafe type systems. I'm not saying static types do…

> multiple dispatch, which is strictly more powerful. In a language that supports classes I can have class B inherit from class A and automatically provide all of class A's functionality without adding a single extra line of code. I can extend class B's functionality by adding only code that is specific to it. I don't see how to do that with multiple dispatch, at least the way it's implemented in Julia.

Single-dispatch OOP dispatches (implicitly) only on the first argument, self. That is how Class B can provide the functionality of A. Multiple dispatch can dispatch on all arguments. Thus, OOP single dispatch is a special case of multiple dispatch.

In your example, functionality in class B can be written simply as ordinary generic functions, which are inferred to their most general compatible type without annotations. Because of this, all functionality for class A will work for class B, as long as B is a superset of A. Not a single line of code, and no brittle inheritance hierarchies.

Multiple dispatch is one solution to the expression problem, which both OOP and functional programming suffer from in dual ways. Other ones include Haskell's typeclasses and Ruby's mixins.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#97
post #50

Earlier quoted context omitted.

>In a language that supports classes I can have class B inherit from class A and automatically provide all of class A's functionality without adding a single extra line of code. And people will abuse this to create horrible brittle inheritance hierachies. There's a reason modern languages like Go and Rust deliberately don't support implementation inheritance; to many people it's an antifeature.

The thing about software is that the "one true way" changes every 2 or 3 years. A few decades ago inheritance was considered a key software design principle, then it was abused by many (especially Java programmers, I think), just like any other powerful feature, now it's considered evil. If multiple dispatch becomes as popular as classes/inheritance was, I suspect it will go through the same love/hate cycle. All I kn…

Inheritance is not really all that powerful, assuming that one follows SOLID and especially Liskov substitution. There's very few places where it's actually applicable. Interfaces are much more widely applicable -- defining contracts instead of behaviour makes it much easier to follow SOLID.

I mostly only use inheritance for patching the behaviour of some code I don't own by overriding some specific method. Because that's the only mechanism the language provides to perform such a modification. This is basically the use-case that Julia's multiple dispatch addresses.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#98
post #53

Earlier quoted context omitted.

Interesting, how does deployment work for you? What sort of executables do you ship?

Don't people mostly ship containers nowadays? Or deploy code but standardize on language version. Why t f would you want to ship / deploy a naked executable in 2019?!

* Container images are generally huge. Layer caching helps to the extent that layers are reusable. If you're lucky, you can use something like alpine for smaller huge images. If you write in a language that supports statically linked executables (e.g., Go) then you can get by with a scratch in many cases, but then you could more easily ship a naked executable

* Container images take a long time to build and build caching only works well if your dependency tree is linear (it's not). (Caveat: there are niche alternatives to docker build for which this may not hold, but then you're subject to the other issues with niche tools--support, docs, compat, etc)

* Your deployment target has to have a container runtime compatible with your image format. This is a PITA for end users in many cases.

* Most popular container runtimes make container processes children of the daemon process, not children of the client process. This means killing the parent process will not kill the child process, which means CI environments need to handle all sorts of edge cases. For example, a CI job is waiting on a stuck container to terminate, but eventually times out or the job is killed or similar; each time this happens a container is leaked--this means that CI tools have to support the container runtime explicitly and handle all of these edge cases because it's prohibitively complex for users to manage.

IMO the only advantage (and this is a huge advantage where applicable) for containers is that they can be orchestrated by things like Kubernetes or AWS Fargate.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#99
post #27

Earlier quoted context omitted.

> multiple dispatch, which is strictly more powerful. In a language that supports classes I can have class B inherit from class A and automatically provide all of class A's functionality without adding a single extra line of code. I can extend class B's functionality by adding only code that is specific to it. I don't see how to do that with multiple dispatch, at least the way it's implemented in Julia.

>In a language that supports classes I can have class B inherit from class A and automatically provide all of class A's functionality without adding a single extra line of code. And people will abuse this to create horrible brittle inheritance hierachies. There's a reason modern languages like Go and Rust deliberately don't support implementation inheritance; to many people it's an antifeature.

In TXR Lisp, I doubled down on OOP and extended the object system to support multiple inheritance, just this December.

Real inheritance of code and data allows for mixin programming, which is very useful.

If you don't give OOP programmers the tools for mixing programming, they will find some other way to do it, such as some unattractive design pattern that fills their code with boilerplate, secondary objects, and unnecessary additional run-time switching and whatnot, all of which can be as brittle as any inheritance hierarchy, if not more.

Re: JuliaLang: The Ingredients for a Composable Programming Language

#100
post #50

Earlier quoted context omitted.

The thing about software is that the "one true way" changes every 2 or 3 years. A few decades ago inheritance was considered a key software design principle, then it was abused by many (especially Java programmers, I think), just like any other powerful feature, now it's considered evil. If multiple dispatch becomes as popular as classes/inheritance was, I suspect it will go through the same love/hate cycle. All I kn…

Inheritance is not really all that powerful, assuming that one follows SOLID and especially Liskov substitution. There's very few places where it's actually applicable. Interfaces are much more widely applicable -- defining contracts instead of behaviour makes it much easier to follow SOLID. I mostly only use inheritance for patching the behaviour of some code I don't own by overriding some specific method. Because t…

It's important to always remember the context that SOLID is a collection of one man's opinions.

When we mix classes to create a new class, the ingredients in the mixture retain their adherence to their respective contracts, and we didn't have to re-implement them.

> I mostly only use inheritance for patching the behaviour of some code.

That's good for you, but you have to realize that classes specifically designed as inheritance bases are also a thing and the experience of using those kinds of classes with inheritance is not the same as deriving from any random class whose behavior we don't like in some aspect.

The conventions by which a class supports inheritance are also a form of contract! The contract says that if you derive from me, you can expect certain behaviors, and also have certain responsibilities regarding what to implement and how, and what not to depend on or not to do and such.

If a class is not designed for inheritance, then there is no contract, beyond some superficial expectations that come from the OOP system, some of which can fall victim to hostilities in the way the class is implemented, or maintained in the future.

Post reply on HN