Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

You can do both. Check out the difference between `import` and `using`: https://docs.julialang.org/en/v1/manual/modules/


I think you mean you can do `foo(x, y, z)` instead of `M.foo(x, y, z)`.

You cannot do `x.foo(y, z)` instead of `foo(x, y, z)`, a feature I sorely miss in Julia. Nim is awesome in this regard. There are some functions / paradigms that are just better represented by `x.foo(y, z)`. Chaining functions in particular in typescript / javascript / rust is SOOO nice. Specifically, in Julia a lot of times I want to create a immutable struct with multiple fields, many of which have defaults. In Julia none of ways seem clean to accomplish this. In rust, something like this is very common:

  let m = App::new("My Program")
    .author("Me, me@mail.com")
    .version("1.0.2")
    .about("Explains in brief what the program does")
    .arg(
        Arg::new("in_file").index(1)
    )
  
In Julia the same thing is:

   m = App("My program")
   m = author(m, "Me, me@mail.com")
   m = version(m, "1.0.2")
   m = about(m, "Explains in brief what the program does")
   m = arg(m, index(Arg("in_file"), 1))
I think with improvements to the pipe operator this can be better but right now I find this painful to read / write.


> immutable struct with multiple fields, many of which have defaults

With `Base.@kwdef` (or the enhanced `@with_kw` from Parameters.jl) on the struct definition, that example can be:

      m = App(name = "My program", 
              author = "Me, me@mail.com",
              version = "1.0.2",
              about = "Explains in brief what the program does",
              arg = index(Arg("in_file"), 1)

which seems pretty nice to me.

Also, there's Chain.jl for a better pipe operator, though I agree improvements to the Base pipe would be great.

To the original point, the problem with x.foo(y, z) is that it would be highly misleading in that it seems to suggest that x is somehow special to the dispatch of the call, which isn't true. While superficially it can feel more familiar, it would instead become a trap for people giving them a wrong mental model of the call's semantics.


That uses keyword arguments though which is bad for performance, which is the main reason I'd like to use immutable structs.


Unless you have some very weird use case (and probably even then), that sounds like a bad application of the "keyword arguments bad for performance" mental model.

The reason to use immutable structs is better performance when you use them, not when you construct them - how often are you constructing new struct objects that the constructor performance is a significant issue? And if you are constructing many many thousands of objects to the level it becomes a performance concern, any difference from keyword arguments will be easily dwarfed by the cost of actually constructing the struct in memory.

Also, these constructors ar simply passing on these named arguments to the non-keyword constructors. Anything complex you're doing during construction will be happening in the non-keyword constructors, and those do get specialized to have good performance; these keyword constructors are simply providing a small, simple interface to them, in a way that shouldn't affect performance in any measurable way.


I have never noticed them being bad for performance. Are you really sure?


Since keyword arguments don't participate in multiple dispatch, they can't be used for compile-time specialization of methods based on their type. That can be a performance issue in specific scenarios, but I think they've taken that as a general rule and misapplied it here (as I mentioned in my sibling comment). For this scenario, that aspect of keyword arguments is most likely irrelevant.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: