Re: Undefine mixed data

2023-03-21 Thread Polgár Márton
(Since this mail couldn't be delivered at first, I'll try to 
aggressively split it this time...)


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.


Re: Undefine mixed data

2023-03-21 Thread Polgár Márton



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 `Nil`s in `Scalar`s
is OK except when the `Scalar`s 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 somewhere else.



For obvious reasons I'm not going to look for examples of this use in
`Array`s 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. (To be 
continued.)


Re: Undefine mixed data

2023-03-21 Thread Polgár Márton
Grr, sorry for the spam. After all this trying, the last part still 
couldn't be delivered. So here is the whole message instead: 
https://gist.github.com/2colours/53b3c3108b0a44fa559eeed0370c26bf.


Re: Undefine mixed data

2023-03-21 Thread Ralph Mellor
I see weaknesses in my attempt to explain Raku's design related to
"definedness".

(I personally think there would best be a documentation page dedicated to the
triumvirate of definiteness, definedness, and truthiness, but here I'm trying to
achieve a balance between being short enough for this context -- an email in a
thread about the deprecation of `undefine` -- and long enough to outline the key
aspects of this carefully designed part of Raku, enough so folk might stop just
assuming it is broken in ways that it's not. The issue really is just
`undefine`,
and where we go next now it is deprecated, not assuming there's some big
broad problem due to ignorance of Raku's design.)

On Mon, Mar 20, 2023 at 10:42 PM Ralph Mellor  wrote:
>
> Let me first summarize relevant parts of Raku's design. These are not
> going to change. They've been in place for 2 decades and work great.

That bit I'm confident about.

I'm also happy with the "definiteness" paragraph and OK with the "truthiness"
paragraph. (Also, the latter is a well known concept in PLs so I don't feel I
need to unduly worry about nailing the latter. Hopefully it just makes sense
to readers even without me being especially careful.)

It's my "definedness" description that seems to me potentially problematic.
I feel like I didn't do a good enough job. Here's my attempt to
sufficiently fix it:

> If a value is indefinite (eg the type object `Tree`) then it is not defined.

If an object is indefinite (eg the type object `Tree`) then, if it is treated as
a potentially defined value (eg `.defined` is called on it as a test, or one of
the constructs that test the `.defined` value is used, such as `with`), then it
is considered not defined.

> A `Failure` instance is definite (because it's an instance, per the previous
> paragraph), yet it is undefined (because it's an instance of a failure).

A `Failure` instance is definite (because it's an instance, per the previous
paragraph), yet is not defined (so that code that tests its definedness, by
calling `.defined`, will know that something is amiss. (At the opposite
extreme, if code carelessly treats a value as if it is fine, without making
any attempt to check, and it's a failure instance, it will "blow up", throwing
an exception.)



If anyone reads this I'd appreciate hearing whether they are happy that I
wrote this email, even if they disagree with my appreciation of the merits
of Raku's design.

--
love, ralph


Re: Undefine mixed data

2023-03-21 Thread Polgár Márton
If you made actual evidential arguments why it's good that Nil gets fed 
into @variables on assignment, or why is it good that @variables are, 
yes, both defined and DEFINITE when only declared, why this 
inconsistency, or counterpointing design,with $variables, is a good 
thing, we could discuss that.


However, you didn't, so now I'm left with personal impressions. You seem 
like the kind of user that Perl 6 should have never created: a user who 
is desperately willing to fix themselves when the language is shaking. I 
think replicating this mentality, i.e teaching people that they just 
have to learn harder, every single time they have a sensible and 
consistent complaint about the language, is much more dangerous than 
planting the thought that, as promised, Perl 6 made new mistakes, as 
opposed to the old Perl 5 mistakes. I think it's only fair that if I 
demonstrate a problem, building upon the experience of others, and point 
out a direction in which it could be improved, then that's legitimate 
impact. Really, let people think that there is a big broad problem in 
Raku's design - which is not a unique thing among programming languages 
really; part of the reason there is so many of them! - , and give them 
ways to cope, and hope for improvements. For the people, that's 
healthier than recognizing the problem nevertheless, but finding out 
that it's denied.


You probably know that Nil is far from being two decades old, or the 
Great List Refactor. These are things that took place before the first 
official release but they were also much bigger changes than the one we 
are talking about. It *is *possible to change the language, and it is 
sometimes desirable as well.


For defined and DEFINITE - I think you are correct and I don't know 
myself how to properly explain it. Horribile dictu: I think this part of 
the language is overwhelmingly complicated, way beyond usefulness. But I 
don't think it's downright contradictory. Another example would be Empty 
which is clearly DEFINITE, yet not defined.


Anyway, it doesn't help us with the @variables that start from being 
both DEFINITE and defined while $variables start from being not DEFINITE 
and clearly not defined.




Re: Undefine mixed data

2023-03-21 Thread Vadim Belman

I'm unable to follow the whole thread in depth, but the point I'd like to make 
is directly related to the initial example. My question would be: what exactly 
do we undefine? I mean, all the discussion about definedness and truthiness is 
undoubtedly great, and I mean no pun here. Special thanks Ralph for clarifying 
some stuff which I never spoke out explicitly to myself. Yet, the matter of 
containerization seems to be left aside to no purpose.

First of all, what would [1,@a].map(-> \v { v.VAR.^name }) produce? Double 
Scalar.

Second, what sense `1.&undefined` makes? None. For sure, it fails.

1 and 2 together, what happens when we `[1, @a].map: *.&undefine`? We use the 
scalar int the 0th array element, then we use... Array? But @a is scalarised 
too, according to .VAR result! As a matter of fact, what we have is:

my $a0 = 1; my $a1 = @a; ($a0, $a1).map: *.&undefine;

In a consistent case one with knowledge of containers would rather expect it to 
be `$a0 = Nil; $a1 = Nil;` Therefore, the original array of `[1, @a]` should 
end up being `[$(Any), $(Any)]`.

One can say that Scalar container transparency is very much a matter of 
convention. In this case what sense does `undefine` makes on an Array? As a 
container, it cannot be undefined as such. And how term 'undefine' turns into 
'emptify' remains kind of mystery. :)

Another aspect of conventions about transparency is that why are we transparent 
depending on the containerized value? For example, `for` doesn't care, it 
either sees an item, or it sees an iterable – period. And, suddenly, there is 
an exception! Because, otherwise, my initial example should've thrown on `1` 
the same way, as in `1.&undefine`. But it doesn't and this break the principle 
of equality in the face of law.

One way or another, I don't an alternative to the deprecation. I also agree to 
the question (I think it was Ralph who expressed it) of what do we expect from 
the routine? Falsification, undefining, or ...? Say, we introduce method 
`reset`. It would drop all containers to their defaults. But what about 
non-containerized values? What about containerization of array elements? Say, 
for the non-containers the method may do nothing as this is their default 
value. But array elements?

The case would be more clear if we replace array with a list: `(1, @a, $b)` In 
this case the containerization is preserved and the behavior is unambiguous. It 
also points at the array case and makes the situation more towards element 
container having priority over it's value. After all, we always can `@a[1] := 
[1,2]` and end up with array being the item's container.

But at this point let's sit back for a moment and think of this: you see a 
problem in my reasoning about how hypothetical `reset` method could act then it 
means others may lean either towards my view, or yours and this segregation of 
views makes method's existence rather problematic. Unless some kind of voting 
would display overwhelming majority of one party. ;)

Just to conclude, I'm not trying to prove something. Just sharing thoughts.

Best regards,
Vadim Belman

> On Mar 13, 2023, at 11:42 PM, rir  wrote:
> 
> 
>undefine seen at:
>  , line 1
>Will be removed with release v6.e!
>Please use another way: assign a Nil; for Arrays/Hashes, assign Empty or 
> () instead.
> 
> Will that deprecation require a conditional and two assignments
> for mixed data?
> 
> [$a, @a, $b, %c, $c, &d].map: { .&undefine};
> 
> [$a, @a, $b, %c, $c, &d].map(
>{ $_ = $_ ~~ (Associative,Positional).any ?? Empty !! Nil });
> 



Re: Undefine mixed data

2023-03-21 Thread rir
On Mon, Mar 20, 2023 at 10:42:45PM +, Ralph Mellor wrote:
> On Mon, Mar 20, 2023 at 12:49 AM rir  wrote:
> >
> > I did, and do, recognize the validity of the problem of 'undefine' not
> > not aligning with '.defined'.
> 
> But do you understand the problem I was trying to communicate?

Possibly not.  "Truthiness" has always seemed sensible when read, but
today I submitted an issue to get it in the doc's glossary.  It seems
just a neologism for 'evaluates True in boolean context.'

> What you're writing suggests to me you know some other PL(s) that
> have notions of truthiness and definedness that don't match Raku's,
> and thus you don't recognize the problem, thinking it's just some trivial
> name clash between `undefine` and `.defined`. It isn't. I'll have another

On reflection, my use of 'undefine' was pure dwimery without reference
to the documentation.  That cuts both ways on the _problem_ I was focused
upon:  the small loss of utility, the recommended replacements are not as
comprehensive.

> go at explaining. I apologize in advance if I again miss the mark, but I
> still hope the penny will drop if I persevere. Wish us luck!

Banked in the mind--a penny's a pound.

> Let me first summarize relevant parts of Raku's design. These are not
> going to change. They've been in place for 2 decades and work great.

> In Raku, whether or not something is considered definite is determined
> by an approach called "definiteness". An instance is definite. A type object
> is indefinite. There are no other possibilities. This notion of definiteness
> corresponds to the linguistic one that arises in many human languages.
> Consider a tree. One either means a definite tree, that large oak at the
> corner of the street, or an indefinite one, the idea of a tree. An instance,
> that oak, is definite. The idea, the type object `Tree`, is indefinite.

Well said. To restate: indefinite lacks, in some manner, a boundary;
definite is bounded and so indicates a specific tree or identifiable set
of trees.

> In Raku, whether or not something is considered defined is determined
> by an approach called "definedness". If a value is indefinite (eg the type
> object `Tree`) then it is not defined. Always. By contrast, definite values
> (instances) *are* defined by default, but there are exceptions. A `Failure`

The default inherited from Mu.

> instance is definite (because it's an instance, per the previous paragraph),
> yet it is undefined (because it's an instance of a failure).

This is unhelpful. The 'previous paragraph' is good common English but
lacks a technical focus.   I see `my $f = Failure` and `my $i = Int`
as very similar, but that the Int type object is apt to indicate
something that never arrived or died away, whilst the Failure type
object is likely soon to be born.

Your

my @a := Array;

is helpful as it demonstrates a container action which I never
considered.  

And, in language/control, I found:

Assigning Empty will effectively undefine an Array ...

which is definitely not the text which I previously read.

Be well,
Rob