Why I can't set what parameters are mutable explicitly?

How do we distinguish between …

Did I say sometimes that Julia, at this moment can do this?!? You and others responders tries to convince me that is so easy and what ever.

As long as f(T) and f(const T) are the same function we are already in DEEP trouble even on Earth the rest is not important. In this moment the language is an endless source of coruption and frustration as you pointed too.

I think you are thinking of design features of the language as bugs. this will not be a helpful situation for you. Perhaps Julia is not for your projects.

For my projects, It’s amazing and very important and why I choose Julia that at any given time suddenly a new function specialized to new types can crop up at run-time and provide new and composable features.

I have the impression that you want as soon as

function foo!(a,b!)
   a[1] = 1
end

Is entered into the REPL or perhaps included that you get an error.

Presumably, you would also want

function foo(a,b)
   bar(a) + bar(b)
end

to give an error if bar mutates its values…

But whether bar mutates its values is not even in principle decidable at the time the parser reads the code. (for example, the function bar may not have a definition at all at the time the code is read)

This is the core of the issue.

8 Likes

It is possible to make too much of Julia’s dynamism: A static checker could ensure that a generic function’s specification is met. Unfortunately there is not currently a checker capable of doing this.

Only if it can determine every possible run-time type that could possibly be handed to every function. Since some functions could take user input, and since “eval” is a function, this can’t in general be done.

A checker would have to be written on the assumption that no methods violating the specification are added after it is run. Such an assumption is reasonable in many cases and would undoubtedly help users avoid bugs.

That “design feature” is just not yet complete implemented if we want to solve coruption and MANY future problems better solve this thing ASAP. How dare me to suggest that design philosophy is wrong?!?

A C++ example to show that parameter constness generates different function names.

void f(int &) {}
void f(const int &) {}

void main()
{
	std::cout << typeid(&f).name();
}

returns on VS.C++ compiler:
void (__cdecl*)(int & __ptr64)
void (__cdecl*)(int const & __ptr64)

I think you’re just confused about how pass-by-sharing works, C++ is not pass-by-sharing btw. FYI: How to pass an object by reference and value in Julia? - Stack Overflow.

As you know, in C++ even when you do something like const int*, it only make the pointer value constant, you can still mutate the content of the vector.

In some sense, Julia is always const, you can never mutate the variable binding in the caller’s scope from a callee, unlike, C++

9 Likes

Exactly, for example:

julia> a = 1
1

julia> b = 2
2

julia> function foo(a,b)
       a = 2; b =3 ;
       end
foo (generic function with 1 method)

julia> foo(a,b)
3

julia> a
1

julia> b
2
1 Like

I hope you don’t try to teach me C or C++ after beind an over 35 professional C/C++ programmer. This is the reason I didn’t use a pointer in my example because maybe, someone will come with this irrelevant and out of topic answer. So where are pointers in my example?!? I hope you are not confused.

Stop mistifying “The Julian Way”. Julia is just yet another young language that starts to run in the very same problems that other languages had too and they find the solution for over 30 years, in C++ case.

whats the point of this line of discussion?!? A lot of languages passes simple small types by value and big objects implicit by reference. All this topic is about other things.

you don’t need a pointer variable in C++ to have “data corruption”? i.e., user sees int a = 3 not a pointer

#include <iostream>

void func(int &a){
    a = 4;
}

int main(){
    int a = 3;
    func(a);
    std::cout<<a<<std::endl;
}

>./test
4

Julia’s variable passing model makes this impossible, period

6 Likes

Thank you @jling!

exactly! But unfortunatelly is just the opposite! You just forgot to add a const in the parameter definition?!?!
void func(const int &a) instead of what you wrote there?!?!

btw if u correct your example the compiler will not compile.

void func(const int &a) { a = 4; }

error C3892: ‘a’: you cannot assign to a variable that is const

Thank you for helping me.

yeah, so consider in Julia it’s always set const an nobody, including Julia developers who are 30 years behind you, can’t accidentally forgot const keyword and accidentally mutate your variable when being called

what do you want more?

1 Like

But in Julia it’s 100% impossible. The fundamental model of how things are passed is different. The called function can never gain access to the bindings that the caller has. There is no need for const because of how it works.

1 Like

What is the more concerning case is when both the caller and the callee are sharing the same heap memory.

function foo()
   a = zeros(10) # allocates some heap memory and makes a "a reference to that array"
   bar(a)
   a
end
function bar(a)
   a[1] = 1
   a = ones(10)
end

It’s not possible for bar to make foo’s a point to different memory (unlike c++). So after bar returns a will be the array [1 0 0 0 0 0 0 0 0 0] rather than a new array with [1 1 1 1…] but it is possible for bar to munge around in the memory that foo is referring to by the name “a”

I would not be so dramatic to say that is impossible. Julia language is just a level of indirection over Julia compiler (that is level of inderection over… and so on 'cuz are over 6 levels of indirections) so everything can be solved if we keep an open mind we just need to mangle constantness/mutability of parameters in the name internaly used by the compiler … just like everybody else. This will get rid of very serious problems in future and open the language to large scale software development and not only simple experiments.

I don’t know if this will work easy on Julia 1.x however.

I still don’t know what you’re proposing / complaining, I think it’s clear at this point any and all “safeguard” made possible by const annotation in C++ is already applied in Julia because Julia adopts pass-by-sharing, so whatever you’re proposing here would be something additional, and I’m not sure what you want

I think @Dan_Micsa is proposing that this give an error:

function f(const a)
  a.x = 1
end

mutable struct A
x
end

v = A(0)
f(v) # error

what about

  a.x[1] = 1

?

my question is basically how strong this effect is and is this kind of analysis even possible in ANY language that allows aliasing?

2 Likes