As a comparison, this is how OCaml handles the same issue.  OCaml uses 
built namespaces, meaning you can only use what was defined before you 
first of all, and if you want something to be able to refer to itself or 
something later on then you need to mark it explicitly

```
let v = v + 1
```

In Ocaml generates the error:
```
Line 1, 8: Error: Unbound value v
```

And even if you mark it as hoisting it to be bound in its own namespace via:
```
let rec v = v + 1
```

That is still not allowed because a value cannot reference itself:
```
Line 1, 12: Error: This kind of expression is not allowed as right-hand 
side of `let rec'
```

However, if it were a function (`()` is just an empty tuple, a convenient 
no-arg argument):
```
let rec v () = (v ()) + 1
```

Then that compiles, and as expected it will recurse forever if called.  ^.^

That is what I want Elm to do.  :-)


For an explanation of how/why this issue is possible at all, do feel free 
to ignore this section, but all of the examples you gave stem from the same 
problem, which is caused by two design decisions hitting each other, the 
first of which is because Elm uses a unified namespace, meaning you can 
define anything anywhere in a file, value or function, where in OCaml it 
has to be in order, but even in OCaml by using `let rec` and `and` you can 
do the same namespacing style as Elm and it will still not allow recursive 
values, but again that is because of the way Elm handles function, which is 
the second reason; in OCaml a binding is either a value (never recursive) 
or a function (and a function is also always 1 input to 1 output, although 
the output can be another function), Elm acts more like that everything is 
a function hence why a 'value' like `v = v + 1` is possible, it acts like a 
function of zero arguments that can then call itself, so that is more equal 
to OCaml's `let rec v () = (v ()) + 1`, however Elm still compiles it to a 
value, specifically it compiles it to, in javascript, `var 
_user$testProject$TestProject$v = _user$testProject$TestProject$v + 1`, 
where javascript has an OCaml-like built namespace, thus things can only 
reference what was built prior to it, however javascript has the oddity 
where when a `val` is defined the 'name' is bound before it is given a 
value (like a `let rec` in OCaml without the `and`, to be able to be used 
for recursive function calls, however this means that when the name is 
defined it is set to 'undefined' as it has not yet been defined even though 
it has been bound (like doing `var v` by itself), thus `var v = v + 1` is 
equal to doing `var v = undefined + 1`, which becomes `var v = NaN`.  This 
is fixable in Elm in a few ways, such as by perhaps separating zero-arg 
function to n-arg functions in the compiler, or by changing how namespacing 
works, either would fix this particular issue (although I do wish it would 
change both).  I'm curious which direction will be taken as it will change 
some semantics about the language as a whole (though changing the 0-arg 
function/value handling to not bound a name before usage would be a less 
noticeable change, I do wish the namespace would change to a built 
namespace, although that means that 'main' would always be at the bottom of 
a file then so I do not see this change happening).


On Friday, September 30, 2016 at 2:13:31 PM UTC-6, J. E. Marca wrote:
>
>
>
> On Friday, September 30, 2016 at 12:46:25 PM UTC-7, Noah Hall wrote:
>>
>> This is a known issue. See this -> 
>> https://github.com/elm-lang/elm-compiler/issues/873 
>>
>> Sorry for the noise then. 
>  
>
>> It will be fixed in 0.18. 
>>
>>
> Oh cool.  I'll read up on the fix and see how it was/will be done. 
>  
> Regards,
> James
>

-- 
You received this message because you are subscribed to the Google Groups "Elm 
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to