Skip to content

Instantly share code, notes, and snippets.

@2colours
Created March 21, 2023 13:57
Show Gist options
  • Save 2colours/53b3c3108b0a44fa559eeed0370c26bf to your computer and use it in GitHub Desktop.
Save 2colours/53b3c3108b0a44fa559eeed0370c26bf to your computer and use it in GitHub Desktop.

Dear Ralph,

I'm sorry that you get frustrated but this is still for all intents and purposes a technical discussion so I don't think it does any good to be vocal about it. There are good points and bad points, arguments and counter-arguments. I can also get upset when I feel indifference or dishonesty in a response that's meant to be an argument but I think a thread like this should read like valuable technical content to an "outsider".

you cannot reasonably indicate for an array that it doesn't have valid content, as opposed to being empty by chance If you mean indicate it's undefined, then here's one way:

my @array;
say @array.elems;      # 0
say @array.so;         # False
say @array.defined;    # True

say @array := Array:U; # (Array:U)
say @array.so;         # False
say @array.defined;    # False

If you mean something else, please be specific. First, it's both inconsistent and inconvenient to have to explicitly bind the variable. Second, once you bound it to the undefined (and indefinite) value, you cannot store elements into it by assignment anymore (there is no auto-vivification either) - so at the end of the day, this is a very similar solution to giving up on @variables altogether, except here you give up on assignment altogether. However, if you want to modify a part of a composite data structure via a container (say, a value you retrieved using .values or some sort of mapping), binding won't help you; you just spoil your own reference to the data you wanted to alter. Again, something that works well for Scalars but nothing else.

it does no good, ever, that you get to store a Nil value ... in an array Why do you think the is default(Nil) idiom for storing Nils in Scalars is OK except when the Scalars are inside an array?

I grant that, as jnthn put it in an SO discussing this:

While there is the is default(Nil) trick, I'd strongly suggest using some other value as your sentinel. Trying to use a language feature in a situation where you don't want the primary behavior it exists to provide will generally not go smoothly. So, it is not something most Rakoons are likely to ever want. But that's the rule that proves the exception -- on rare occasions some Rakoons do want to store a Nil in an array because it's not a sentinel but a Nil representing a Nil.

I still remember very well the discussion where among several people, Larry Wall pointed out that Nil is designed to not act like a usual value. Yes, you can bind to it - I suppose if you want it to show up in an array so much, you could bind it there, even though it's a bad idea among the people who know the most about the intents and design of Raku -, furthermore, you can set it as a default for a container - but the latter could be as much taken as a skeleton falling out of the cupboard, or, if you don't like this visuals, enough rope to shoot yourself in the foot.

Also, since Arrays don't actually contain all the containers of the universe when they are created - rather just know a way to "animate" new containers - I can imagine that setting is default(Nil) may even cause discrepancy som

For obvious reasons I'm not going to look for examples of this use in Arrays to share them in this thread.

On the other hand, let me show you examples where the lackiness of @variables causes inconvenience, that, in my opinion, would test the patience (and sense of reality) of any newcomer to the language.

Say, you have a subroutine that takes a named array, so you'd like to have :@value as a parameter. Mind you, I don't think this should sound awkward in general - but anyway, a very basic use-case would be the MAIN subroutine itself, and designing a CLI with a named argument that can take multiple values.

First off, default assignment to the parameter seems to do something that looks more like "the right thing" (perhaps binding) because sub demo(:@values = Nil) { dd @values; }; demo(); is a type error: "Type check failed in binding to parameter '@values'; expected Positional but got Nil (Nil)". Second - if you decide against setting any sort of default value, the distinction is just lost. You just get an empty Array which is in accordance to variable declarations, and sinks the distinction between the missing named argument and a perfectly valid empty Array (more accurately: Positional) argument which is so explicit that it is bound into the parameter, not just stored.

The annoying thing is that this has an easy "fix" (binding to the type object, like you did), yet that "fix" cannot be the default behavior, in compliance with the same problematic non-distinguishing behavior of variable declarations.

All in all, I think there is discrepancy between the proposed and the actual role of @variables (and %variables alike). Usually, we act as if they were first-class kinds of a variable, like $variables - however, they don't have a mutable identity which is a fundamental property of variables all across the programming world. This means, if you might want to completely rewrite, swap, undefine, etc. an Array, you'll be better off using a $variable with a type constraint. And this is where I ask: if we have these sigils built into the language and reasoned about, if we pretend they are as useful as $variables (even though $variables can wrap @variables and %variables, keeping the good parts PLUS adding a mutable identity) - can we do something to make @variables more useful? If we pretend there is sort of a trinity of the three major sigils (not counting the "unsigil"), can we not provide at least a unified way to clear the content of these variables?

This has gotten a bit long but some points needed to be elaborated. Please bear in mind that my objective is to find an approach and a resolution for the issues I notice, not to mock the language for fun. Still, I don't think it's healthy to wipe certain complaints off the table, and explain problems away. As they say: "do it better". If you think it's good the way it is, prove it by example that it's good. If you don't, then think of spaces for improvement. With these matters, I fall into the latter category. If you prove it by example that the current way has significant positives that would need to be sacrificed, that can change the discussion in the direction you desire apparently.

In an ideal world, we can learn, preserve common knowledge and share thoughts in these mails, and that's going to be what I for one will remember in one month time. Have a nice and relaxed day.

Martin

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment