yeah, it abuses the fact that Dyalog allows some extra chars as identifiers to squeeze in the custom overrides that won't clash with user-defined things
but the result having an unknown type bleeds into the current environment either way
and eval is just the simple example. The worse one is {1 ⍵.field 2} - ⍵.field could be a function, thus dyadically called, or an array, thus making a 3-item strand
and the even worse one is {1 variable 2} where the surrounding code could be constantly switching variable between function/array/operator
and fwiw, namespace.⍳ can be used to execute ⍳ (or any other builtin) with the ⎕IO/⎕ML/etc of a specific namespace, not the surrounding one, so there's already a sort of meaning for builtins in a namespace
and the way that syntax works is that namespace.(expression) is literally the expression evaluated within the scope of the namespace, so you can't really even define ⍳ as a key anyways
@dzaima It seems to me all of these issues comes down to the fact that symbols could be dynamically changed from functions to variables in the middle of the execution of a function. How common is it really that this is needed?
relardless of how needed it is, you still have to at least handle the namespace field reading varying types, otherwise you have a very weird language where the first execution of a function defines what it does or something
@dzaima I mean, I see two approaches: One is to have a strict separation of what is a function vs variable. BQN does this with casing. Another is to have a way to declare what a certain symbol is. This second approach would work well in APL I think. Simply say that foo is a function, and then it'll be parsed as such. Trying to assign a value to foo would result in an error.
My guess is that very little existing APL code would break with such a restriction.
The point I'm trying to make is that there is very little sensible code where you have some expression x y z where the code would do the right thing regardless of whether y is a function or a value (other than some ticks that are more clever than they should be)
@EliasMårtenson yeah, that's not wrong, but there's also very little sensible code where you're indexing out-of-bounds, but some people still decide to not make that break the whole language
right, you can duplicate the body for that. Doesn't work for {⍵.a ⍵.b ⍵.c ⍵.d ⍵.e ⍵.f ⍵.g ⍵.h ⍵.i ⍵.j}, which has up to 1024 variations of what it could mean
there's just not really anything a language can do with a "this is mostly the case"
@dzaima Well, there is extended. So they could extend it even further by imposing limitations on reassignment of functions to values. If so, they can pre-parse a dfn instead of reparsing every invocation.
I like a lot of things about Dyalog, and I'm impressed by the performance in many cases. It's just that when I use dfns (especially in conjunction with ¨) performance just drops like a rock.
@dzaima A very mild type system, like Common Lisp if you like, that has a DECLARE form that allows you to provide extra information that the compiler may or may not choose to take advantage of.
So I could tell the Dyalog compiler that anything in the following file will always be evaluated with ⎕IO←0
@user107162 I see. Maybe have a look at our list of learning resources to see if there is something else that fits you? Otherwise, people here will surely be happy to help.